Merge lp:~matthewpetroff/inkscape/gsoc-2013-unit-improvement into lp:~inkscape.dev/inkscape/trunk
- gsoc-2013-unit-improvement
- Merge into trunk
Status: | Merged |
---|---|
Merged at revision: | 12554 |
Proposed branch: | lp:~matthewpetroff/inkscape/gsoc-2013-unit-improvement |
Merge into: | lp:~inkscape.dev/inkscape/trunk |
Diff against target: |
4078 lines (+1192/-753) 101 files modified
share/templates/A4.svg (+2/-1) share/templates/A4_landscape.svg (+2/-1) share/templates/CD_cover_300dpi.svg (+2/-1) share/templates/Letter.svg (+3/-2) share/templates/Letter_landscape.svg (+3/-2) share/templates/business_card_85x54mm.svg (+2/-1) share/templates/business_card_90x50mm.svg (+2/-1) share/templates/default.be.svg (+2/-1) share/templates/default_mm.svg (+2/-1) share/templates/default_pt.svg (+2/-1) share/ui/Makefile.am (+0/-1) share/ui/units.txt (+0/-20) src/arc-context.cpp (+1/-0) src/connector-context.cpp (+2/-0) src/desktop.cpp (+5/-5) src/document.cpp (+28/-13) src/document.h (+3/-2) src/draw-context.cpp (+1/-0) src/dyna-draw-context.cpp (+4/-0) src/ege-adjustment-action.cpp (+25/-3) src/ege-adjustment-action.h (+12/-2) src/extension/internal/cairo-renderer-pdf-out.cpp (+1/-1) src/extension/internal/cairo-renderer.cpp (+4/-4) src/extension/internal/emf-inout.cpp (+2/-2) src/extension/internal/emf-print.cpp (+3/-3) src/extension/internal/grid.cpp (+3/-2) src/extension/internal/latex-pstricks.cpp (+4/-4) src/extension/internal/latex-text-renderer.cpp (+2/-2) src/extension/internal/odf.cpp (+2/-1) src/extension/internal/pdfinput/pdf-parser.cpp (+3/-3) src/extension/internal/pdfinput/svg-builder.cpp (+1/-1) src/extension/internal/wmf-inout.cpp (+2/-2) src/extension/internal/wmf-print.cpp (+2/-2) src/file.cpp (+2/-2) src/flood-context.cpp (+2/-2) src/helper/pixbuf-ops.cpp (+2/-2) src/helper/png-write.cpp (+2/-1) src/inkview.cpp (+4/-3) src/lpe-tool-context.cpp (+2/-2) src/main.cpp (+4/-4) src/object-snapper.cpp (+3/-3) src/persp3d.cpp (+4/-3) src/rect-context.cpp (+1/-0) src/selection-chemistry.cpp (+5/-5) src/shape-editor.cpp (+6/-0) src/shape-editor.h (+3/-0) src/sp-ellipse.cpp (+53/-0) src/sp-ellipse.h (+1/-0) src/sp-flowtext.cpp (+39/-0) src/sp-flowtext.h (+7/-0) src/sp-guide.cpp (+1/-1) src/sp-item-group.cpp (+78/-0) src/sp-item-group.h (+1/-0) src/sp-item.cpp (+4/-2) src/sp-root.h (+1/-1) src/sp-spiral.cpp (+52/-1) src/sp-spiral.h (+1/-0) src/sp-star.cpp (+49/-0) src/sp-star.h (+1/-0) src/sp-text.cpp (+7/-2) src/sp-text.h (+6/-0) src/spiral-context.cpp (+1/-0) src/star-context.cpp (+1/-0) src/style.cpp (+15/-15) src/svg-view-widget.cpp (+3/-2) src/svg-view.cpp (+7/-6) src/text-context.cpp (+1/-0) src/ui/clipboard.cpp (+2/-2) src/ui/dialog/aboutbox.cpp (+3/-2) src/ui/dialog/document-properties.cpp (+60/-3) src/ui/dialog/document-properties.h (+3/-0) src/ui/dialog/export.cpp (+3/-3) src/ui/dialog/print.cpp (+6/-6) src/ui/dialog/text-edit.cpp (+1/-1) src/ui/widget/page-sizer.cpp (+35/-29) src/ui/widget/page-sizer.h (+6/-2) src/ui/widget/spinbutton.cpp (+13/-5) src/ui/widget/spinbutton.h (+5/-0) src/util/expression-evaluator.cpp (+323/-463) src/util/expression-evaluator.h (+93/-23) src/util/units.cpp (+62/-10) src/util/units.h (+10/-14) src/widgets/calligraphy-toolbar.cpp (+8/-8) src/widgets/connector-toolbar.cpp (+3/-3) src/widgets/desktop-widget.cpp (+2/-2) src/widgets/eraser-toolbar.cpp (+1/-1) src/widgets/gradient-toolbar.cpp (+3/-2) src/widgets/icon.cpp (+2/-1) src/widgets/mesh-toolbar.cpp (+2/-2) src/widgets/node-toolbar.cpp (+2/-2) src/widgets/paintbucket-toolbar.cpp (+2/-2) src/widgets/pencil-toolbar.cpp (+1/-0) src/widgets/rect-toolbar.cpp (+10/-9) src/widgets/select-toolbar.cpp (+3/-2) src/widgets/spiral-toolbar.cpp (+1/-1) src/widgets/spray-toolbar.cpp (+6/-6) src/widgets/star-toolbar.cpp (+2/-2) src/widgets/text-toolbar.cpp (+6/-0) src/widgets/toolbox.cpp (+4/-2) src/widgets/toolbox.h (+5/-0) src/widgets/tweak-toolbar.cpp (+3/-3) |
To merge this branch: | bzr merge lp:~matthewpetroff/inkscape/gsoc-2013-unit-improvement |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Martin Owens | code review | Approve | |
Review via email: mp+185928@code.launchpad.net |
Commit message
Description of the change
Implements real world document units using a viewBox, uses real world units for document size, and extends expression evaluator to toolbars
su_v (suv-lp) wrote : | # |
Units for rectangle tool don't match document units.
Steps to reproduce:
1) launch branch (default prefs)
2) open template 'A4 Page'
(this document has a view box, and sets the scale to real units via height and width)
3) switch to the rectangle tool, and draw a rectangle of 10x10mm
(enter the numbers in the controls bar of the rectangle tool)
4) remove stroke from rectangle (to allow easier comparing of the geometric size)
4) switch to the select tool, and check the size of the rectangle (default unit is 'mm'):
the select tool claims that the rectangle has the size of 35.433 x 35.433 mm
- 12503. By Matthew Petroff
-
Fix bug in rectangle toolbar.
Matthew Petroff (matthewpetroff) wrote : | # |
> Units for rectangle tool don't match document units.
>
> Steps to reproduce:
> 1) launch branch (default prefs)
> 2) open template 'A4 Page'
> (this document has a view box, and sets the scale to real units via height
> and width)
> 3) switch to the rectangle tool, and draw a rectangle of 10x10mm
> (enter the numbers in the controls bar of the rectangle tool)
> 4) remove stroke from rectangle (to allow easier comparing of the geometric
> size)
> 4) switch to the select tool, and check the size of the rectangle (default
> unit is 'mm'):
> the select tool claims that the rectangle has the size of 35.433 x 35.433
> mm
The rectangle toolbar was hard coded to pixels. I fixed it, so it now uses the document unit.
- 12504. By Matthew Petroff
-
Merge from trunk.
su_v (suv-lp) wrote : | # |
On 2013-09-20 19:09 +0200, <email address hidden> wrote:
> The proposal to merge lp:~matthewpetroff/inkscape/gsoc-2013-unit-improvement into lp:inkscape has been updated.
>
> Status: Needs review => Merged
@Matthew - after the merge, building trunk r12552 with dbusapi enabled fails:
CXX extension/
../../src/
../../src/
../../src/
../../src/
../../src/
../../src/
make[3]: *** [extension/
make[2]: *** [all] Error 2
make[1]: *** [all-recursive] Error 1
make: *** [all] Error 2
Any chance you could take a look? You probably know best how to fix this ;)
Please let me know if you prefer to have a bug report filed about the build failure.
Matthew Petroff (matthewpetroff) wrote : | # |
It should be fixed now. Can you test it? I've never built Inkscape with dbus enabled.
su_v (suv-lp) wrote : | # |
On 2013-09-20 20:57 +0200, Matthew Petroff wrote:
> It should be fixed now. Can you test it? I've never built Inkscape with dbus enabled.
Fix confirmed - r12555 builds successfully with dbusapi enabled.
Thank you for the prompt response!
Preview Diff
1 | === modified file 'share/templates/A4.svg' |
2 | --- share/templates/A4.svg 2013-08-10 13:23:01 +0000 |
3 | +++ share/templates/A4.svg 2013-09-20 17:05:49 +0000 |
4 | @@ -9,7 +9,8 @@ |
5 | xmlns:cc="http://web.resource.org/cc/" |
6 | xmlns:dc="http://purl.org/dc/elements/1.1/" |
7 | width="210mm" |
8 | - height="297mm"> |
9 | + height="297mm" |
10 | + viewBox="0 0 210 297"> |
11 | <defs |
12 | id="defs3" /> |
13 | <sodipodi:namedview |
14 | |
15 | === modified file 'share/templates/A4_landscape.svg' |
16 | --- share/templates/A4_landscape.svg 2013-08-10 13:23:01 +0000 |
17 | +++ share/templates/A4_landscape.svg 2013-09-20 17:05:49 +0000 |
18 | @@ -9,7 +9,8 @@ |
19 | xmlns:cc="http://web.resource.org/cc/" |
20 | xmlns:dc="http://purl.org/dc/elements/1.1/" |
21 | width="297mm" |
22 | - height="210mm"> |
23 | + height="210mm" |
24 | + viewBox="0 0 297 210"> |
25 | <defs /> |
26 | <sodipodi:namedview |
27 | inkscape:document-units="mm" |
28 | |
29 | === modified file 'share/templates/CD_cover_300dpi.svg' |
30 | --- share/templates/CD_cover_300dpi.svg 2013-08-10 13:23:01 +0000 |
31 | +++ share/templates/CD_cover_300dpi.svg 2013-09-20 17:05:49 +0000 |
32 | @@ -9,7 +9,8 @@ |
33 | xmlns:cc="http://web.resource.org/cc/" |
34 | xmlns:dc="http://purl.org/dc/elements/1.1/" |
35 | width="343pt" |
36 | - height="340pt"> |
37 | + height="340pt" |
38 | + viewBox="0 0 343 340"> |
39 | <defs /> |
40 | <sodipodi:namedview |
41 | pagecolor="#ffffff" |
42 | |
43 | === modified file 'share/templates/Letter.svg' |
44 | --- share/templates/Letter.svg 2013-08-10 13:23:01 +0000 |
45 | +++ share/templates/Letter.svg 2013-09-20 17:05:49 +0000 |
46 | @@ -8,8 +8,9 @@ |
47 | xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" |
48 | xmlns:cc="http://web.resource.org/cc/" |
49 | xmlns:dc="http://purl.org/dc/elements/1.1/" |
50 | - width="612pt" |
51 | - height="792pt"> |
52 | + width="8.5in" |
53 | + height="11in" |
54 | + viewBox="0 0 8.5 11"> |
55 | <defs /> |
56 | <sodipodi:namedview |
57 | inkscape:document-units="in" |
58 | |
59 | === modified file 'share/templates/Letter_landscape.svg' |
60 | --- share/templates/Letter_landscape.svg 2013-08-10 13:23:01 +0000 |
61 | +++ share/templates/Letter_landscape.svg 2013-09-20 17:05:49 +0000 |
62 | @@ -8,8 +8,9 @@ |
63 | xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" |
64 | xmlns:cc="http://web.resource.org/cc/" |
65 | xmlns:dc="http://purl.org/dc/elements/1.1/" |
66 | - width="792pt" |
67 | - height="612pt"> |
68 | + width="11in" |
69 | + height="8.5in" |
70 | + viewBox="0 0 11 8.5"> |
71 | <defs /> |
72 | <sodipodi:namedview |
73 | inkscape:document-units="in" |
74 | |
75 | === modified file 'share/templates/business_card_85x54mm.svg' |
76 | --- share/templates/business_card_85x54mm.svg 2013-08-10 13:23:01 +0000 |
77 | +++ share/templates/business_card_85x54mm.svg 2013-09-20 17:05:49 +0000 |
78 | @@ -9,7 +9,8 @@ |
79 | xmlns:cc="http://web.resource.org/cc/" |
80 | xmlns:dc="http://purl.org/dc/elements/1.1/" |
81 | width="85mm" |
82 | - height="54mm"> |
83 | + height="54mm" |
84 | + viewBox="0 0 85 54"> |
85 | <defs |
86 | id="defs3" /> |
87 | <sodipodi:namedview |
88 | |
89 | === modified file 'share/templates/business_card_90x50mm.svg' |
90 | --- share/templates/business_card_90x50mm.svg 2013-08-10 13:23:01 +0000 |
91 | +++ share/templates/business_card_90x50mm.svg 2013-09-20 17:05:49 +0000 |
92 | @@ -9,7 +9,8 @@ |
93 | xmlns:cc="http://web.resource.org/cc/" |
94 | xmlns:dc="http://purl.org/dc/elements/1.1/" |
95 | width="90mm" |
96 | - height="50mm"> |
97 | + height="50mm" |
98 | + viewBox="0 0 90 50"> |
99 | <defs |
100 | id="defs3" /> |
101 | <sodipodi:namedview |
102 | |
103 | === modified file 'share/templates/default.be.svg' |
104 | --- share/templates/default.be.svg 2009-09-29 17:39:54 +0000 |
105 | +++ share/templates/default.be.svg 2013-09-20 17:05:49 +0000 |
106 | @@ -9,7 +9,8 @@ |
107 | xmlns:cc="http://web.resource.org/cc/" |
108 | xmlns:dc="http://purl.org/dc/elements/1.1/" |
109 | width="210mm" |
110 | - height="297mm"> |
111 | + height="297mm" |
112 | + viewBox="0 0 210 297"> |
113 | <defs /> |
114 | <sodipodi:namedview |
115 | id="base" |
116 | |
117 | === modified file 'share/templates/default_mm.svg' |
118 | --- share/templates/default_mm.svg 2006-01-16 02:36:01 +0000 |
119 | +++ share/templates/default_mm.svg 2013-09-20 17:05:49 +0000 |
120 | @@ -9,7 +9,8 @@ |
121 | xmlns:cc="http://web.resource.org/cc/" |
122 | xmlns:dc="http://purl.org/dc/elements/1.1/" |
123 | width="210mm" |
124 | - height="297mm"> |
125 | + height="297mm" |
126 | + viewBox="0 0 210 297"> |
127 | <defs /> |
128 | <sodipodi:namedview |
129 | id="base" |
130 | |
131 | === modified file 'share/templates/default_pt.svg' |
132 | --- share/templates/default_pt.svg 2006-01-16 02:36:01 +0000 |
133 | +++ share/templates/default_pt.svg 2013-09-20 17:05:49 +0000 |
134 | @@ -9,7 +9,8 @@ |
135 | xmlns:cc="http://web.resource.org/cc/" |
136 | xmlns:dc="http://purl.org/dc/elements/1.1/" |
137 | width="210mm" |
138 | - height="297mm"> |
139 | + height="297mm" |
140 | + viewBox="0 0 595.27558 841.88974"> |
141 | <defs /> |
142 | <sodipodi:namedview |
143 | id="base" |
144 | |
145 | === modified file 'share/ui/Makefile.am' |
146 | --- share/ui/Makefile.am 2006-01-16 02:36:01 +0000 |
147 | +++ share/ui/Makefile.am 2013-09-20 17:05:49 +0000 |
148 | @@ -5,7 +5,6 @@ |
149 | keybindings.rc \ |
150 | menus-bars.xml \ |
151 | toolbox.xml \ |
152 | - units.txt \ |
153 | units.xml |
154 | |
155 | EXTRA_DIST = $(ui_DATA) |
156 | |
157 | === removed file 'share/ui/units.txt' |
158 | --- share/ui/units.txt 2012-03-22 19:19:09 +0000 |
159 | +++ share/ui/units.txt 1970-01-01 00:00:00 +0000 |
160 | @@ -1,20 +0,0 @@ |
161 | -# Simple unit configuration file |
162 | -# |
163 | -# This is a space-delimited list of unit definitions. |
164 | - |
165 | -# name name_plural abbr type factor PRI description |
166 | -# --------------------------------------------------------------------------- |
167 | - % % % DIMENSIONLESS 1.00 Y Percentage |
168 | - pixel pixels px LINEAR 1.00 Y CSS Pixels (90/inch) |
169 | - point points pt LINEAR 1.25 N PostScript points (72/inch) |
170 | - pica picas pc LINEAR 15.0 N 12 points |
171 | - inch inches in LINEAR 90.0 N Inches (90 px/in) |
172 | - millimeter millimeters mm LINEAR 3.543307 N Millimeters (25.4 mm/in) |
173 | - centimeter centimeters cm LINEAR 35.43307 N Centimeters (10 mm/cm) |
174 | - meter meters m LINEAR 3543.307 N Meters (100 cm/m) |
175 | - foot feet ft LINEAR 1080 N Feet (12 in/ft) |
176 | - degree degrees ° RADIAL 1.00 Y Degrees |
177 | - radian radians rad RADIAL 57.296 N Radians (57.296 deg/rad) |
178 | - font-height font-heights em FONT_HEIGHT 1.00 Y Font height |
179 | - x-height x-heights ex FONT_HEIGHT 0.50 N Height of letter 'x' |
180 | - half-em half-ems en FONT_HEIGHT 0.50 N Half of font height |
181 | |
182 | === modified file 'src/arc-context.cpp' |
183 | --- src/arc-context.cpp 2013-08-30 21:35:42 +0000 |
184 | +++ src/arc-context.cpp 2013-09-20 17:05:49 +0000 |
185 | @@ -451,6 +451,7 @@ |
186 | } |
187 | |
188 | this->arc->updateRepr(); |
189 | + this->arc->doWriteTransform(this->arc->getRepr(), this->arc->transform, NULL, true); |
190 | |
191 | desktop->canvas->endForcedFullRedraws(); |
192 | |
193 | |
194 | === modified file 'src/connector-context.cpp' |
195 | --- src/connector-context.cpp 2013-07-31 19:11:20 +0000 |
196 | +++ src/connector-context.cpp 2013-09-20 17:05:49 +0000 |
197 | @@ -998,6 +998,8 @@ |
198 | cc->newconn->updateRepr(); |
199 | } |
200 | |
201 | + cc->newconn->doWriteTransform(cc->newconn->getRepr(), cc->newconn->transform, NULL, true); |
202 | + |
203 | // Only set the selection after we are finished with creating the attributes of |
204 | // the connector. Otherwise, the selection change may alter the defaults for |
205 | // values like curvature in the connector context, preventing subsequent lookup |
206 | |
207 | === modified file 'src/desktop.cpp' |
208 | --- src/desktop.cpp 2013-09-19 04:26:02 +0000 |
209 | +++ src/desktop.cpp 2013-09-20 17:05:49 +0000 |
210 | @@ -242,7 +242,7 @@ |
211 | // display rect and zoom are now handled in sp_desktop_widget_realize() |
212 | |
213 | Geom::Rect const d(Geom::Point(0.0, 0.0), |
214 | - Geom::Point(document->getWidth(), document->getHeight())); |
215 | + Geom::Point(document->getWidth().value("px"), document->getHeight().value("px"))); |
216 | |
217 | SP_CTRLRECT(page)->setRectangle(d); |
218 | SP_CTRLRECT(page_border)->setRectangle(d); |
219 | @@ -259,7 +259,7 @@ |
220 | |
221 | |
222 | /* Connect event for page resize */ |
223 | - _doc2dt[5] = document->getHeight(); |
224 | + _doc2dt[5] = document->getHeight().value("px"); |
225 | sp_canvas_item_affine_absolute (SP_CANVAS_ITEM (drawing), _doc2dt); |
226 | |
227 | _modified_connection = namedview->connectModified(sigc::bind<2>(sigc::ptr_fun(&_namedview_modified), this)); |
228 | @@ -1108,7 +1108,7 @@ |
229 | SPDesktop::zoom_page() |
230 | { |
231 | Geom::Rect d(Geom::Point(0, 0), |
232 | - Geom::Point(doc()->getWidth(), doc()->getHeight())); |
233 | + Geom::Point(doc()->getWidth().value("px"), doc()->getHeight().value("px"))); |
234 | |
235 | if (d.minExtent() < 1.0) { |
236 | return; |
237 | @@ -1125,12 +1125,12 @@ |
238 | { |
239 | Geom::Rect const a = get_display_area(); |
240 | |
241 | - if (doc()->getWidth() < 1.0) { |
242 | + if (doc()->getWidth().value("px") < 1.0) { |
243 | return; |
244 | } |
245 | |
246 | Geom::Rect d(Geom::Point(0, a.midpoint()[Geom::Y]), |
247 | - Geom::Point(doc()->getWidth(), a.midpoint()[Geom::Y])); |
248 | + Geom::Point(doc()->getWidth().value("px"), a.midpoint()[Geom::Y])); |
249 | |
250 | set_display_area(d, 10); |
251 | } |
252 | |
253 | === modified file 'src/document.cpp' |
254 | --- src/document.cpp 2013-09-16 17:32:58 +0000 |
255 | +++ src/document.cpp 2013-09-20 17:05:49 +0000 |
256 | @@ -548,16 +548,20 @@ |
257 | return NULL; |
258 | } |
259 | |
260 | -gdouble SPDocument::getWidth() const |
261 | +Inkscape::Util::Quantity SPDocument::getWidth() const |
262 | { |
263 | - g_return_val_if_fail(this->priv != NULL, 0.0); |
264 | - g_return_val_if_fail(this->root != NULL, 0.0); |
265 | + g_return_val_if_fail(this->priv != NULL, Inkscape::Util::Quantity(0.0, Inkscape::Util::Unit())); |
266 | + g_return_val_if_fail(this->root != NULL, Inkscape::Util::Quantity(0.0, Inkscape::Util::Unit())); |
267 | |
268 | - gdouble result = root->width.computed; |
269 | + gdouble result = root->width.value; |
270 | + SVGLength::Unit u = root->width.unit; |
271 | if (root->width.unit == SVGLength::PERCENT && root->viewBox_set) { |
272 | result = root->viewBox.width(); |
273 | } |
274 | - return result; |
275 | + if (u == SVGLength::NONE) { |
276 | + u = SVGLength::PX; |
277 | + } |
278 | + return Inkscape::Util::Quantity(result, unit_table.getUnit(u)); |
279 | } |
280 | |
281 | void SPDocument::setWidth(const Inkscape::Util::Quantity &width) |
282 | @@ -584,16 +588,20 @@ |
283 | root->updateRepr(); |
284 | } |
285 | |
286 | -gdouble SPDocument::getHeight() const |
287 | +Inkscape::Util::Quantity SPDocument::getHeight() const |
288 | { |
289 | - g_return_val_if_fail(this->priv != NULL, 0.0); |
290 | - g_return_val_if_fail(this->root != NULL, 0.0); |
291 | + g_return_val_if_fail(this->priv != NULL, Inkscape::Util::Quantity(0.0, Inkscape::Util::Unit())); |
292 | + g_return_val_if_fail(this->root != NULL, Inkscape::Util::Quantity(0.0, Inkscape::Util::Unit())); |
293 | |
294 | - gdouble result = root->height.computed; |
295 | + gdouble result = root->height.value; |
296 | + SVGLength::Unit u = root->height.unit; |
297 | if (root->height.unit == SVGLength::PERCENT && root->viewBox_set) { |
298 | result = root->viewBox.height(); |
299 | } |
300 | - return result; |
301 | + if (u == SVGLength::NONE) { |
302 | + u = SVGLength::PX; |
303 | + } |
304 | + return Inkscape::Util::Quantity(result, unit_table.getUnit(u)); |
305 | } |
306 | |
307 | void SPDocument::setHeight(const Inkscape::Util::Quantity &height) |
308 | @@ -620,9 +628,16 @@ |
309 | root->updateRepr(); |
310 | } |
311 | |
312 | +void SPDocument::setViewBox(const Geom::Rect &viewBox) |
313 | +{ |
314 | + root->viewBox_set = true; |
315 | + root->viewBox = viewBox; |
316 | + root->updateRepr(); |
317 | +} |
318 | + |
319 | Geom::Point SPDocument::getDimensions() const |
320 | { |
321 | - return Geom::Point(getWidth(), getHeight()); |
322 | + return Geom::Point(getWidth().value("px"), getHeight().value("px")); |
323 | } |
324 | |
325 | Geom::OptRect SPDocument::preferredBounds() const |
326 | @@ -644,7 +659,7 @@ |
327 | double const w = rect.width(); |
328 | double const h = rect.height(); |
329 | |
330 | - double const old_height = getHeight(); |
331 | + double const old_height = getHeight().value("px"); |
332 | Inkscape::Util::Unit const px = unit_table.getUnit("px"); |
333 | |
334 | /* in px */ |
335 | @@ -979,7 +994,7 @@ |
336 | if (root->viewBox_set) { // if set, take from viewBox |
337 | ctx->viewport = root->viewBox; |
338 | } else { // as a last resort, set size to A4 |
339 | - ctx->viewport = Geom::Rect::from_xywh(0, 0, 210 * Inkscape::Util::Quantity::convert(1, "mm", "px"), 297 * Inkscape::Util::Quantity::convert(1, "mm", "px")); |
340 | + ctx->viewport = Geom::Rect::from_xywh(0, 0, Inkscape::Util::Quantity::convert(210, "mm", "px"), Inkscape::Util::Quantity::convert(297, "mm", "px")); |
341 | } |
342 | ctx->i2vp = Geom::identity(); |
343 | } |
344 | |
345 | === modified file 'src/document.h' |
346 | --- src/document.h 2013-08-30 21:35:42 +0000 |
347 | +++ src/document.h 2013-09-20 17:05:49 +0000 |
348 | @@ -227,12 +227,13 @@ |
349 | |
350 | SPDocument *doRef(); |
351 | SPDocument *doUnref(); |
352 | - gdouble getWidth() const; |
353 | - gdouble getHeight() const; |
354 | + Inkscape::Util::Quantity getWidth() const; |
355 | + Inkscape::Util::Quantity getHeight() const; |
356 | Geom::Point getDimensions() const; |
357 | Geom::OptRect preferredBounds() const; |
358 | void setWidth(const Inkscape::Util::Quantity &width); |
359 | void setHeight(const Inkscape::Util::Quantity &height); |
360 | + void setViewBox(const Geom::Rect &viewBox); |
361 | void requestModified(); |
362 | gint ensureUpToDate(); |
363 | bool addResource(const gchar *key, SPObject *object); |
364 | |
365 | === modified file 'src/draw-context.cpp' |
366 | --- src/draw-context.cpp 2013-08-04 13:09:03 +0000 |
367 | +++ src/draw-context.cpp 2013-09-20 17:05:49 +0000 |
368 | @@ -599,6 +599,7 @@ |
369 | dc->selection->set(repr); |
370 | Inkscape::GC::release(repr); |
371 | item->transform = SP_ITEM(desktop->currentLayer())->i2doc_affine().inverse(); |
372 | + item->doWriteTransform(item->getRepr(), item->transform, NULL, true); |
373 | item->updateRepr(); |
374 | } |
375 | |
376 | |
377 | === modified file 'src/dyna-draw-context.cpp' |
378 | --- src/dyna-draw-context.cpp 2013-07-31 19:11:20 +0000 |
379 | +++ src/dyna-draw-context.cpp 2013-09-20 17:05:49 +0000 |
380 | @@ -958,6 +958,10 @@ |
381 | sp_desktop_selection(desktop)->set(this->repr); |
382 | } |
383 | } |
384 | + |
385 | + SPItem *item=SP_ITEM(desktop->doc()->getObjectByRepr(this->repr)); |
386 | + item->doWriteTransform(item->getRepr(), item->transform, NULL, true); |
387 | + |
388 | } else { |
389 | if (this->repr) { |
390 | sp_repr_unparent(this->repr); |
391 | |
392 | === modified file 'src/ege-adjustment-action.cpp' |
393 | --- src/ege-adjustment-action.cpp 2013-01-26 19:33:04 +0000 |
394 | +++ src/ege-adjustment-action.cpp 2013-09-20 17:05:49 +0000 |
395 | @@ -115,6 +115,7 @@ |
396 | gchar* appearance; |
397 | gchar* iconId; |
398 | Inkscape::IconSize iconSize; |
399 | + Inkscape::UI::Widget::UnitTracker *unitTracker; |
400 | }; |
401 | |
402 | #define EGE_ADJUSTMENT_ACTION_GET_PRIVATE( o ) ( G_TYPE_INSTANCE_GET_PRIVATE( (o), EGE_ADJUSTMENT_ACTION_TYPE, EgeAdjustmentActionPrivate ) ) |
403 | @@ -128,7 +129,8 @@ |
404 | PROP_TOOL_POST, |
405 | PROP_APPEARANCE, |
406 | PROP_ICON_ID, |
407 | - PROP_ICON_SIZE |
408 | + PROP_ICON_SIZE, |
409 | + PROP_UNIT_TRACKER |
410 | }; |
411 | |
412 | enum { |
413 | @@ -234,6 +236,13 @@ |
414 | (int)Inkscape::ICON_SIZE_SMALL_TOOLBAR, |
415 | (GParamFlags)(G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT) ) ); |
416 | |
417 | + g_object_class_install_property( objClass, |
418 | + PROP_UNIT_TRACKER, |
419 | + g_param_spec_pointer( "unit_tracker", |
420 | + "Unit Tracker", |
421 | + "The widget that keeps track of the unit", |
422 | + (GParamFlags)(G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT) ) ); |
423 | + |
424 | g_type_class_add_private( klass, sizeof(EgeAdjustmentActionClass) ); |
425 | } |
426 | } |
427 | @@ -263,6 +272,7 @@ |
428 | action->private_data->appearance = 0; |
429 | action->private_data->iconId = 0; |
430 | action->private_data->iconSize = Inkscape::ICON_SIZE_SMALL_TOOLBAR; |
431 | + action->private_data->unitTracker = NULL; |
432 | } |
433 | |
434 | static void ege_adjustment_action_finalize( GObject* object ) |
435 | @@ -292,7 +302,8 @@ |
436 | const gchar *tooltip, |
437 | const gchar *stock_id, |
438 | gdouble climb_rate, |
439 | - guint digits ) |
440 | + guint digits, |
441 | + Inkscape::UI::Widget::UnitTracker *unit_tracker ) |
442 | { |
443 | GObject* obj = (GObject*)g_object_new( EGE_ADJUSTMENT_ACTION_TYPE, |
444 | "name", name, |
445 | @@ -302,6 +313,7 @@ |
446 | "adjustment", adjustment, |
447 | "climb-rate", climb_rate, |
448 | "digits", digits, |
449 | + "unit_tracker", unit_tracker, |
450 | NULL ); |
451 | |
452 | EgeAdjustmentAction* action = EGE_ADJUSTMENT_ACTION( obj ); |
453 | @@ -349,6 +361,10 @@ |
454 | g_value_set_int( value, action->private_data->iconSize ); |
455 | break; |
456 | |
457 | + case PROP_UNIT_TRACKER: |
458 | + g_value_set_pointer( value, action->private_data->unitTracker ); |
459 | + break; |
460 | + |
461 | default: |
462 | G_OBJECT_WARN_INVALID_PROPERTY_ID( obj, propId, pspec ); |
463 | } |
464 | @@ -450,6 +466,12 @@ |
465 | } |
466 | break; |
467 | |
468 | + case PROP_UNIT_TRACKER: |
469 | + { |
470 | + action->private_data->unitTracker = (Inkscape::UI::Widget::UnitTracker*)g_value_get_pointer( value ); |
471 | + } |
472 | + break; |
473 | + |
474 | default: |
475 | G_OBJECT_WARN_INVALID_PROPERTY_ID( obj, propId, pspec ); |
476 | } |
477 | @@ -812,7 +834,7 @@ |
478 | gtk_scale_button_set_icons( GTK_SCALE_BUTTON(spinbutton), floogles ); |
479 | } else { |
480 | if ( gFactoryCb ) { |
481 | - spinbutton = gFactoryCb( act->private_data->adj, act->private_data->climbRate, act->private_data->digits ); |
482 | + spinbutton = gFactoryCb( act->private_data->adj, act->private_data->climbRate, act->private_data->digits, act->private_data->unitTracker ); |
483 | } else { |
484 | spinbutton = gtk_spin_button_new( act->private_data->adj, act->private_data->climbRate, act->private_data->digits ); |
485 | } |
486 | |
487 | === modified file 'src/ege-adjustment-action.h' |
488 | --- src/ege-adjustment-action.h 2011-06-03 10:44:52 +0000 |
489 | +++ src/ege-adjustment-action.h 2013-09-20 17:05:49 +0000 |
490 | @@ -63,6 +63,14 @@ |
491 | typedef struct _EgeAdjustmentActionClass EgeAdjustmentActionClass; |
492 | typedef struct _EgeAdjustmentActionPrivate EgeAdjustmentActionPrivate; |
493 | |
494 | +namespace Inkscape { |
495 | + namespace UI { |
496 | + namespace Widget { |
497 | + class UnitTracker; |
498 | + } |
499 | + } |
500 | +} |
501 | + |
502 | /** |
503 | * Instance structure of EgeAdjustmentAction. |
504 | */ |
505 | @@ -95,7 +103,7 @@ |
506 | */ |
507 | |
508 | /** Callback type for widgets creation factory */ |
509 | -typedef GtkWidget* (*EgeCreateAdjWidgetCB)( GtkAdjustment *adjustment, gdouble climb_rate, guint digits ); |
510 | +typedef GtkWidget* (*EgeCreateAdjWidgetCB)( GtkAdjustment *adjustment, gdouble climb_rate, guint digits, Inkscape::UI::Widget::UnitTracker *unit_tracker ); |
511 | |
512 | /** |
513 | * Sets a factory callback to be used to create the specific widget. |
514 | @@ -117,6 +125,7 @@ |
515 | * @param stock_id Icon id to use. |
516 | * @param climb_rate Used for created widgets. |
517 | * @param digits Used for created widgets. |
518 | + * @param unit_tracker Used to store unit. |
519 | */ |
520 | EgeAdjustmentAction* ege_adjustment_action_new( GtkAdjustment* adjustment, |
521 | const gchar *name, |
522 | @@ -124,7 +133,8 @@ |
523 | const gchar *tooltip, |
524 | const gchar *stock_id, |
525 | gdouble climb_rate, |
526 | - guint digits |
527 | + guint digits, |
528 | + Inkscape::UI::Widget::UnitTracker *unit_tracker |
529 | ); |
530 | /** |
531 | * Returns a pointer to the GtkAdjustment represented by the given |
532 | |
533 | === modified file 'src/extension/internal/cairo-renderer-pdf-out.cpp' |
534 | --- src/extension/internal/cairo-renderer-pdf-out.cpp 2013-08-26 20:03:43 +0000 |
535 | +++ src/extension/internal/cairo-renderer-pdf-out.cpp 2013-09-20 17:05:49 +0000 |
536 | @@ -197,7 +197,7 @@ |
537 | |
538 | float new_bleedmargin_px = 0.; |
539 | try { |
540 | - new_bleedmargin_px = mod->get_param_float("bleed") * Inkscape::Util::Quantity::convert(1, "mm", "px"); |
541 | + new_bleedmargin_px = Inkscape::Util::Quantity::convert(mod->get_param_float("bleed"), "mm", "px"); |
542 | } |
543 | catch(...) { |
544 | g_warning("Parameter <bleed> might not exist"); |
545 | |
546 | === modified file 'src/extension/internal/cairo-renderer.cpp' |
547 | --- src/extension/internal/cairo-renderer.cpp 2013-09-19 17:03:35 +0000 |
548 | +++ src/extension/internal/cairo-renderer.cpp 2013-09-20 17:05:49 +0000 |
549 | @@ -463,8 +463,8 @@ |
550 | } |
551 | |
552 | // The width and height of the bitmap in pixels |
553 | - unsigned width = ceil(bbox->width() * (res / Inkscape::Util::Quantity::convert(1, "in", "px"))); |
554 | - unsigned height = ceil(bbox->height() * (res / Inkscape::Util::Quantity::convert(1, "in", "px"))); |
555 | + unsigned width = ceil(bbox->width() * Inkscape::Util::Quantity::convert(res, "px", "in")); |
556 | + unsigned height = ceil(bbox->height() * Inkscape::Util::Quantity::convert(res, "px", "in")); |
557 | |
558 | if (width == 0 || height == 0) return; |
559 | |
560 | @@ -638,9 +638,9 @@ |
561 | Geom::Affine tp( Geom::Translate( bleedmargin_px, bleedmargin_px ) ); |
562 | ctx->transform(tp); |
563 | } else { |
564 | - double high = doc->getHeight(); |
565 | + double high = doc->getHeight().value("px"); |
566 | if (ctx->_vector_based_target) |
567 | - high *= Inkscape::Util::Quantity::convert(1, "px", "pt"); |
568 | + high = Inkscape::Util::Quantity::convert(high, "px", "pt"); |
569 | |
570 | // this transform translates the export drawing to a virtual page (0,0)-(width,height) |
571 | Geom::Affine tp(Geom::Translate(-d.left() * (ctx->_vector_based_target ? Inkscape::Util::Quantity::convert(1, "pt", "px") : 1.0), |
572 | |
573 | === modified file 'src/extension/internal/emf-inout.cpp' |
574 | --- src/extension/internal/emf-inout.cpp 2013-09-01 23:39:00 +0000 |
575 | +++ src/extension/internal/emf-inout.cpp 2013-09-20 17:05:49 +0000 |
576 | @@ -1799,8 +1799,8 @@ |
577 | d->MMX = d->MM100InX / 100.0; |
578 | d->MMY = d->MM100InY / 100.0; |
579 | |
580 | - d->PixelsOutX = d->MMX * Inkscape::Util::Quantity::convert(1, "mm", "px"); |
581 | - d->PixelsOutY = d->MMY * Inkscape::Util::Quantity::convert(1, "mm", "px"); |
582 | + d->PixelsOutX = Inkscape::Util::Quantity::convert(d->MMX, "mm", "px"); |
583 | + d->PixelsOutY = Inkscape::Util::Quantity::convert(d->MMY, "mm", "px"); |
584 | |
585 | // Upper left corner, from header rclBounds, in device units, usually both 0, but not always |
586 | d->ulCornerInX = pEmr->rclBounds.left; |
587 | |
588 | === modified file 'src/extension/internal/emf-print.cpp' |
589 | --- src/extension/internal/emf-print.cpp 2013-09-19 00:57:10 +0000 |
590 | +++ src/extension/internal/emf-print.cpp 2013-09-20 17:05:49 +0000 |
591 | @@ -138,8 +138,8 @@ |
592 | |
593 | |
594 | // width and height in px |
595 | - _width = doc->getWidth(); |
596 | - _height = doc->getHeight(); |
597 | + _width = doc->getWidth().value("px"); |
598 | + _height = doc->getHeight().value("px"); |
599 | |
600 | // initialize a few global variables |
601 | hbrush = hbrushOld = hpen = 0; |
602 | @@ -243,7 +243,7 @@ |
603 | g_error("Fatal programming error in PrintEmf::begin at textcomment_set 1"); |
604 | } |
605 | |
606 | - snprintf(buff, sizeof(buff) - 1, "Drawing=%.1lfx%.1lfpx, %.1lfx%.1lfmm", _width, _height, dwInchesX * Inkscape::Util::Quantity::convert(1, "in", "mm"), dwInchesY * Inkscape::Util::Quantity::convert(1, "in", "mm")); |
607 | + snprintf(buff, sizeof(buff) - 1, "Drawing=%.1lfx%.1lfpx, %.1lfx%.1lfmm", _width, _height, Inkscape::Util::Quantity::convert(dwInchesX, "in", "mm"), Inkscape::Util::Quantity::convert(dwInchesY, "in", "mm")); |
608 | rec = textcomment_set(buff); |
609 | if (!rec || emf_append((PU_ENHMETARECORD)rec, et, U_REC_FREE)) { |
610 | g_error("Fatal programming error in PrintEmf::begin at textcomment_set 1"); |
611 | |
612 | === modified file 'src/extension/internal/grid.cpp' |
613 | --- src/extension/internal/grid.cpp 2013-06-07 03:18:19 +0000 |
614 | +++ src/extension/internal/grid.cpp 2013-09-20 17:05:49 +0000 |
615 | @@ -35,6 +35,7 @@ |
616 | #include "extension/effect.h" |
617 | #include "extension/system.h" |
618 | |
619 | +#include "util/units.h" |
620 | |
621 | #include "grid.h" |
622 | |
623 | @@ -97,14 +98,14 @@ |
624 | /* get page size */ |
625 | SPDocument * doc = document->doc(); |
626 | bounding_area = Geom::Rect( Geom::Point(0,0), |
627 | - Geom::Point(doc->getWidth(), doc->getHeight()) ); |
628 | + Geom::Point(doc->getWidth().value("px"), doc->getHeight().value("px")) ); |
629 | } else { |
630 | Geom::OptRect bounds = selection->visualBounds(); |
631 | if (bounds) { |
632 | bounding_area = *bounds; |
633 | } |
634 | |
635 | - gdouble doc_height = (document->doc())->getHeight(); |
636 | + gdouble doc_height = (document->doc())->getHeight().value("px"); |
637 | Geom::Rect temprec = Geom::Rect(Geom::Point(bounding_area.min()[Geom::X], doc_height - bounding_area.min()[Geom::Y]), |
638 | Geom::Point(bounding_area.max()[Geom::X], doc_height - bounding_area.max()[Geom::Y])); |
639 | |
640 | |
641 | === modified file 'src/extension/internal/latex-pstricks.cpp' |
642 | --- src/extension/internal/latex-pstricks.cpp 2013-07-31 22:33:03 +0000 |
643 | +++ src/extension/internal/latex-pstricks.cpp 2013-09-20 17:05:49 +0000 |
644 | @@ -117,8 +117,8 @@ |
645 | } |
646 | |
647 | // width and height in pt |
648 | - _width = doc->getWidth() * Inkscape::Util::Quantity::convert(1, "px", "pt"); |
649 | - _height = doc->getHeight() * Inkscape::Util::Quantity::convert(1, "px", "pt"); |
650 | + _width = doc->getWidth().value("pt"); |
651 | + _height = doc->getHeight().value("pt"); |
652 | |
653 | if (res >= 0) { |
654 | |
655 | @@ -128,10 +128,10 @@ |
656 | os << "\\psset{xunit=.5pt,yunit=.5pt,runit=.5pt}\n"; |
657 | // from now on we can output px, but they will be treated as pt |
658 | |
659 | - os << "\\begin{pspicture}(" << doc->getWidth() << "," << doc->getHeight() << ")\n"; |
660 | + os << "\\begin{pspicture}(" << doc->getWidth().value("px") << "," << doc->getHeight().value("px") << ")\n"; |
661 | } |
662 | |
663 | - m_tr_stack.push( Geom::Scale(1, -1) * Geom::Translate(0, doc->getHeight())); /// @fixme hardcoded doc2dt transform |
664 | + m_tr_stack.push( Geom::Scale(1, -1) * Geom::Translate(0, doc->getHeight().value("px"))); /// @fixme hardcoded doc2dt transform |
665 | |
666 | return fprintf(_stream, "%s", os.str().c_str()); |
667 | } |
668 | |
669 | === modified file 'src/extension/internal/latex-text-renderer.cpp' |
670 | --- src/extension/internal/latex-text-renderer.cpp 2013-09-14 11:09:15 +0000 |
671 | +++ src/extension/internal/latex-text-renderer.cpp 2013-09-20 17:05:49 +0000 |
672 | @@ -633,7 +633,7 @@ |
673 | } |
674 | |
675 | // flip y-axis |
676 | - push_transform( Geom::Scale(1,-1) * Geom::Translate(0, doc->getHeight()) ); /// @fixme hardcoded desktop transform! |
677 | + push_transform( Geom::Scale(1,-1) * Geom::Translate(0, doc->getHeight().value("px")) ); /// @fixme hardcoded desktop transform! |
678 | |
679 | // write the info to LaTeX |
680 | Inkscape::SVGOStringStream os; |
681 | @@ -642,7 +642,7 @@ |
682 | // scaling of the image when including it in LaTeX |
683 | |
684 | os << " \\ifx\\svgwidth\\undefined%\n"; |
685 | - os << " \\setlength{\\unitlength}{" << d.width() * Inkscape::Util::Quantity::convert(1, "px", "pt") << "bp}%\n"; // note: 'bp' is the Postscript pt unit in LaTeX, see LP bug #792384 |
686 | + os << " \\setlength{\\unitlength}{" << Inkscape::Util::Quantity::convert(d.width(), "px", "pt") << "bp}%\n"; // note: 'bp' is the Postscript pt unit in LaTeX, see LP bug #792384 |
687 | os << " \\ifx\\svgscale\\undefined%\n"; |
688 | os << " \\relax%\n"; |
689 | os << " \\else%\n"; |
690 | |
691 | === modified file 'src/extension/internal/odf.cpp' |
692 | --- src/extension/internal/odf.cpp 2013-08-03 01:03:43 +0000 |
693 | +++ src/extension/internal/odf.cpp 2013-09-20 17:05:49 +0000 |
694 | @@ -75,6 +75,7 @@ |
695 | #include "sp-flowtext.h" |
696 | #include "svg/svg.h" |
697 | #include "text-editing.h" |
698 | +#include "util/units.h" |
699 | |
700 | |
701 | //# DOM-specific includes |
702 | @@ -945,7 +946,7 @@ |
703 | //### Get SVG-to-ODF transform |
704 | Geom::Affine tf (item->i2dt_affine()); |
705 | //Flip Y into document coordinates |
706 | - double doc_height = SP_ACTIVE_DOCUMENT->getHeight(); |
707 | + double doc_height = SP_ACTIVE_DOCUMENT->getHeight().value("px"); |
708 | Geom::Affine doc2dt_tf = Geom::Affine(Geom::Scale(1.0, -1.0)); /// @fixme hardcoded desktop transform |
709 | doc2dt_tf = doc2dt_tf * Geom::Affine(Geom::Translate(0, doc_height)); |
710 | tf = tf * doc2dt_tf; |
711 | |
712 | === modified file 'src/extension/internal/pdfinput/pdf-parser.cpp' |
713 | --- src/extension/internal/pdfinput/pdf-parser.cpp 2013-08-06 18:54:40 +0000 |
714 | +++ src/extension/internal/pdfinput/pdf-parser.cpp 2013-09-20 17:05:49 +0000 |
715 | @@ -279,14 +279,14 @@ |
716 | ignoreUndef = 0; |
717 | operatorHistory = NULL; |
718 | builder = builderA; |
719 | - builder->setDocumentSize(state->getPageWidth()*Inkscape::Util::Quantity::convert(1, "pt", "px"), |
720 | - state->getPageHeight()*Inkscape::Util::Quantity::convert(1, "pt", "px")); |
721 | + builder->setDocumentSize(Inkscape::Util::Quantity::convert(state->getPageWidth(), "pt", "px"), |
722 | + Inkscape::Util::Quantity::convert(state->getPageHeight(), "pt", "px")); |
723 | |
724 | double *ctm = state->getCTM(); |
725 | double scaledCTM[6]; |
726 | for (int i = 0; i < 6; ++i) { |
727 | baseMatrix[i] = ctm[i]; |
728 | - scaledCTM[i] = Inkscape::Util::Quantity::convert(1, "pt", "px") * ctm[i]; |
729 | + scaledCTM[i] = Inkscape::Util::Quantity::convert(ctm[i], "pt", "px"); |
730 | } |
731 | saveState(); |
732 | builder->setTransform((double*)&scaledCTM); |
733 | |
734 | === modified file 'src/extension/internal/pdfinput/svg-builder.cpp' |
735 | --- src/extension/internal/pdfinput/svg-builder.cpp 2013-08-06 18:54:40 +0000 |
736 | +++ src/extension/internal/pdfinput/svg-builder.cpp 2013-09-20 17:05:49 +0000 |
737 | @@ -793,7 +793,7 @@ |
738 | Geom::Affine pat_matrix(matrix[0], matrix[1], matrix[2], matrix[3], |
739 | matrix[4], matrix[5]); |
740 | if ( !for_shading && _is_top_level ) { |
741 | - Geom::Affine flip(1.0, 0.0, 0.0, -1.0, 0.0, _height * Inkscape::Util::Quantity::convert(1, "px", "pt")); |
742 | + Geom::Affine flip(1.0, 0.0, 0.0, -1.0, 0.0, Inkscape::Util::Quantity::convert(_height, "px", "pt")); |
743 | pat_matrix *= flip; |
744 | } |
745 | gchar *transform_text = sp_svg_transform_write(pat_matrix); |
746 | |
747 | === modified file 'src/extension/internal/wmf-inout.cpp' |
748 | --- src/extension/internal/wmf-inout.cpp 2013-09-01 23:39:00 +0000 |
749 | +++ src/extension/internal/wmf-inout.cpp 2013-09-20 17:05:49 +0000 |
750 | @@ -1742,8 +1742,8 @@ |
751 | tmp_outdef << " version=\"1.0\"\n"; |
752 | |
753 | tmp_outdef << |
754 | - " width=\"" << d->PixelsOutX/ Inkscape::Util::Quantity::convert(1, "mm", "px") << "mm\"\n" << |
755 | - " height=\"" << d->PixelsOutY/ Inkscape::Util::Quantity::convert(1, "mm", "px") << "mm\">\n"; |
756 | + " width=\"" << Inkscape::Util::Quantity::convert(d->PixelsOutX, "px", "mm") << "mm\"\n" << |
757 | + " height=\"" << Inkscape::Util::Quantity::convert(d->PixelsOutY, "px", "mm") << "mm\">\n"; |
758 | *(d->outdef) += tmp_outdef.str().c_str(); |
759 | *(d->outdef) += "<defs>"; // temporary end of header |
760 | |
761 | |
762 | === modified file 'src/extension/internal/wmf-print.cpp' |
763 | --- src/extension/internal/wmf-print.cpp 2013-09-19 00:57:10 +0000 |
764 | +++ src/extension/internal/wmf-print.cpp 2013-09-20 17:05:49 +0000 |
765 | @@ -138,8 +138,8 @@ |
766 | |
767 | // WMF header the only things that can be set are the page size in inches (w,h) and the dpi |
768 | // width and height in px |
769 | - _width = doc->getWidth(); |
770 | - _height = doc->getHeight(); |
771 | + _width = doc->getWidth().value("px"); |
772 | + _height = doc->getHeight().value("px"); |
773 | |
774 | // initialize a few global variables |
775 | hbrush = hpen = 0; |
776 | |
777 | === modified file 'src/file.cpp' |
778 | --- src/file.cpp 2013-08-14 18:52:42 +0000 |
779 | +++ src/file.cpp 2013-09-20 17:05:49 +0000 |
780 | @@ -149,7 +149,7 @@ |
781 | // If the current desktop is empty, open the document there |
782 | doc->ensureUpToDate(); // TODO this will trigger broken link warnings, etc. |
783 | desktop->change_document(doc); |
784 | - doc->emitResizedSignal(doc->getWidth(), doc->getHeight()); |
785 | + doc->emitResizedSignal(doc->getWidth().value("px"), doc->getHeight().value("px")); |
786 | } else { |
787 | // create a whole new desktop and window |
788 | SPViewWidget *dtw = sp_desktop_widget_new(sp_document_namedview(doc, NULL)); // TODO this will trigger broken link warnings, etc. |
789 | @@ -291,7 +291,7 @@ |
790 | // If the current desktop is empty, open the document there |
791 | doc->ensureUpToDate(); // TODO this will trigger broken link warnings, etc. |
792 | desktop->change_document(doc); |
793 | - doc->emitResizedSignal(doc->getWidth(), doc->getHeight()); |
794 | + doc->emitResizedSignal(doc->getWidth().value("px"), doc->getHeight().value("px")); |
795 | } else { |
796 | // create a whole new desktop and window |
797 | SPViewWidget *dtw = sp_desktop_widget_new(sp_document_namedview(doc, NULL)); // TODO this will trigger broken link warnings, etc. |
798 | |
799 | === modified file 'src/flood-context.cpp' |
800 | --- src/flood-context.cpp 2013-08-30 21:35:42 +0000 |
801 | +++ src/flood-context.cpp 2013-09-20 17:05:49 +0000 |
802 | @@ -764,7 +764,7 @@ |
803 | unsigned int height = (int)ceil(screen.height() * zoom_scale * padding); |
804 | |
805 | Geom::Point origin(screen.min()[Geom::X], |
806 | - document->getHeight() - screen.height() - screen.min()[Geom::Y]); |
807 | + document->getHeight().value("px") - screen.height() - screen.min()[Geom::Y]); |
808 | |
809 | origin[Geom::X] += (screen.width() * ((1 - padding) / 2)); |
810 | origin[Geom::Y] += (screen.height() * ((1 - padding) / 2)); |
811 | @@ -874,7 +874,7 @@ |
812 | } |
813 | |
814 | for (unsigned int i = 0; i < fill_points.size(); i++) { |
815 | - Geom::Point pw = Geom::Point(fill_points[i][Geom::X] / zoom_scale, document->getHeight() + (fill_points[i][Geom::Y] / zoom_scale)) * affine; |
816 | + Geom::Point pw = Geom::Point(fill_points[i][Geom::X] / zoom_scale, document->getHeight().value("px") + (fill_points[i][Geom::Y] / zoom_scale)) * affine; |
817 | |
818 | pw[Geom::X] = (int)MIN(width - 1, MAX(0, pw[Geom::X])); |
819 | pw[Geom::Y] = (int)MIN(height - 1, MAX(0, pw[Geom::Y])); |
820 | |
821 | === modified file 'src/helper/pixbuf-ops.cpp' |
822 | --- src/helper/pixbuf-ops.cpp 2013-09-19 00:57:10 +0000 |
823 | +++ src/helper/pixbuf-ops.cpp 2013-09-20 17:05:49 +0000 |
824 | @@ -115,12 +115,12 @@ |
825 | double padding = 1.0; |
826 | |
827 | Geom::Point origin(screen.min()[Geom::X], |
828 | - doc->getHeight() - screen[Geom::Y].extent() - screen.min()[Geom::Y]); |
829 | + doc->getHeight().value("px") - screen[Geom::Y].extent() - screen.min()[Geom::Y]); |
830 | |
831 | origin[Geom::X] = origin[Geom::X] + (screen[Geom::X].extent() * ((1 - padding) / 2)); |
832 | origin[Geom::Y] = origin[Geom::Y] + (screen[Geom::Y].extent() * ((1 - padding) / 2)); |
833 | |
834 | - Geom::Scale scale( (xdpi / Inkscape::Util::Quantity::convert(1, "in", "px")), (ydpi / Inkscape::Util::Quantity::convert(1, "in", "px"))); |
835 | + Geom::Scale scale(Inkscape::Util::Quantity::convert(xdpi, "px", "in"), Inkscape::Util::Quantity::convert(ydpi, "px", "in")); |
836 | Geom::Affine affine = scale * Geom::Translate(-origin * scale); |
837 | |
838 | /* Create ArenaItems and set transform */ |
839 | |
840 | === modified file 'src/helper/png-write.cpp' |
841 | --- src/helper/png-write.cpp 2012-05-24 05:49:41 +0000 |
842 | +++ src/helper/png-write.cpp 2013-09-20 17:05:49 +0000 |
843 | @@ -34,6 +34,7 @@ |
844 | #include "preferences.h" |
845 | #include "rdf.h" |
846 | #include "display/cairo-utils.h" |
847 | +#include "util/units.h" |
848 | |
849 | /* This is an example of how to use libpng to read and write PNG files. |
850 | * The file libpng.txt is much more verbose then this. If you have not |
851 | @@ -415,7 +416,7 @@ |
852 | doc->ensureUpToDate(); |
853 | |
854 | /* Calculate translation by transforming to document coordinates (flipping Y)*/ |
855 | - Geom::Point translation = Geom::Point(-area[Geom::X][0], area[Geom::Y][1] - doc->getHeight()); |
856 | + Geom::Point translation = Geom::Point(-area[Geom::X][0], area[Geom::Y][1] - doc->getHeight().value("px")); |
857 | |
858 | /* This calculation is only valid when assumed that (x0,y0)= area.corner(0) and (x1,y1) = area.corner(2) |
859 | * 1) a[0] * x0 + a[2] * y1 + a[4] = 0.0 |
860 | |
861 | === modified file 'src/inkview.cpp' |
862 | --- src/inkview.cpp 2013-03-25 17:42:31 +0000 |
863 | +++ src/inkview.cpp 2013-09-20 17:05:49 +0000 |
864 | @@ -54,6 +54,7 @@ |
865 | #include "document.h" |
866 | #include "svg-view.h" |
867 | #include "svg-view-widget.h" |
868 | +#include "util/units.h" |
869 | |
870 | #ifdef WITH_INKJAR |
871 | #include "io/inkjar.h" |
872 | @@ -308,8 +309,8 @@ |
873 | w = gtk_window_new (GTK_WINDOW_TOPLEVEL); |
874 | gtk_window_set_title( GTK_WINDOW(w), ss.doc->getName() ); |
875 | gtk_window_set_default_size (GTK_WINDOW (w), |
876 | - MIN ((int)(ss.doc)->getWidth (), (int)gdk_screen_width () - 64), |
877 | - MIN ((int)(ss.doc)->getHeight (), (int)gdk_screen_height () - 64)); |
878 | + MIN ((int)(ss.doc)->getWidth().value("px"), (int)gdk_screen_width() - 64), |
879 | + MIN ((int)(ss.doc)->getHeight().value("px"), (int)gdk_screen_height() - 64)); |
880 | ss.window = w; |
881 | |
882 | g_signal_connect (G_OBJECT (w), "delete_event", (GCallback) sp_svgview_main_delete, &ss); |
883 | @@ -318,7 +319,7 @@ |
884 | (ss.doc)->ensureUpToDate(); |
885 | ss.view = sp_svg_view_widget_new (ss.doc); |
886 | (ss.doc)->doUnref (); |
887 | - SP_SVG_VIEW_WIDGET(ss.view)->setResize( false, ss.doc->getWidth(), ss.doc->getHeight() ); |
888 | + SP_SVG_VIEW_WIDGET(ss.view)->setResize( false, ss.doc->getWidth().value("px"), ss.doc->getHeight().value("px") ); |
889 | gtk_widget_show (ss.view); |
890 | gtk_container_add (GTK_CONTAINER (w), ss.view); |
891 | |
892 | |
893 | === modified file 'src/lpe-tool-context.cpp' |
894 | --- src/lpe-tool-context.cpp 2013-08-30 21:35:42 +0000 |
895 | +++ src/lpe-tool-context.cpp 2013-09-20 17:05:49 +0000 |
896 | @@ -330,8 +330,8 @@ |
897 | |
898 | void |
899 | lpetool_get_limiting_bbox_corners(SPDocument *document, Geom::Point &A, Geom::Point &B) { |
900 | - Geom::Coord w = document->getWidth(); |
901 | - Geom::Coord h = document->getHeight(); |
902 | + Geom::Coord w = document->getWidth().value("px"); |
903 | + Geom::Coord h = document->getHeight().value("px"); |
904 | Inkscape::Preferences *prefs = Inkscape::Preferences::get(); |
905 | |
906 | double ulx = prefs->getDouble("/tools/lpetool/bbox_upperleftx", 0); |
907 | |
908 | === modified file 'src/main.cpp' |
909 | --- src/main.cpp 2013-08-30 21:35:42 +0000 |
910 | +++ src/main.cpp 2013-09-20 17:05:49 +0000 |
911 | @@ -1535,7 +1535,7 @@ |
912 | g_warning("Export width %lu out of range (1 - %lu). Nothing exported.", width, (unsigned long int)PNG_UINT_31_MAX); |
913 | return 1; |
914 | } |
915 | - dpi = (gdouble) width * Inkscape::Util::Quantity::convert(1, "in", "px") / area.width(); |
916 | + dpi = (gdouble) Inkscape::Util::Quantity::convert(width, "in", "px") / area.width(); |
917 | } |
918 | |
919 | if (sp_export_height) { |
920 | @@ -1545,15 +1545,15 @@ |
921 | g_warning("Export height %lu out of range (1 - %lu). Nothing exported.", height, (unsigned long int)PNG_UINT_31_MAX); |
922 | return 1; |
923 | } |
924 | - dpi = (gdouble) height * Inkscape::Util::Quantity::convert(1, "in", "px") / area.height(); |
925 | + dpi = (gdouble) Inkscape::Util::Quantity::convert(height, "in", "px") / area.height(); |
926 | } |
927 | |
928 | if (!sp_export_width) { |
929 | - width = (unsigned long int) (area.width() * dpi / Inkscape::Util::Quantity::convert(1, "in", "px") + 0.5); |
930 | + width = (unsigned long int) (Inkscape::Util::Quantity::convert(area.width(), "px", "in") * dpi + 0.5); |
931 | } |
932 | |
933 | if (!sp_export_height) { |
934 | - height = (unsigned long int) (area.height() * dpi / Inkscape::Util::Quantity::convert(1, "in", "px") + 0.5); |
935 | + height = (unsigned long int) (Inkscape::Util::Quantity::convert(area.height(), "px", "in") * dpi + 0.5); |
936 | } |
937 | |
938 | guint32 bgcolor = 0x00000000; |
939 | |
940 | === modified file 'src/object-snapper.cpp' |
941 | --- src/object-snapper.cpp 2013-08-03 21:30:12 +0000 |
942 | +++ src/object-snapper.cpp 2013-09-20 17:05:49 +0000 |
943 | @@ -770,7 +770,7 @@ |
944 | |
945 | Geom::PathVector* Inkscape::ObjectSnapper::_getBorderPathv() const |
946 | { |
947 | - Geom::Rect const border_rect = Geom::Rect(Geom::Point(0,0), Geom::Point((_snapmanager->getDocument())->getWidth(),(_snapmanager->getDocument())->getHeight())); |
948 | + Geom::Rect const border_rect = Geom::Rect(Geom::Point(0,0), Geom::Point((_snapmanager->getDocument())->getWidth().value("px"),(_snapmanager->getDocument())->getHeight().value("px"))); |
949 | return _getPathvFromRect(border_rect); |
950 | } |
951 | |
952 | @@ -787,8 +787,8 @@ |
953 | |
954 | void Inkscape::ObjectSnapper::_getBorderNodes(std::vector<SnapCandidatePoint> *points) const |
955 | { |
956 | - Geom::Coord w = (_snapmanager->getDocument())->getWidth(); |
957 | - Geom::Coord h = (_snapmanager->getDocument())->getHeight(); |
958 | + Geom::Coord w = (_snapmanager->getDocument())->getWidth().value("px"); |
959 | + Geom::Coord h = (_snapmanager->getDocument())->getHeight().value("px"); |
960 | points->push_back(SnapCandidatePoint(Geom::Point(0,0), SNAPSOURCE_UNDEFINED, SNAPTARGET_PAGE_CORNER)); |
961 | points->push_back(SnapCandidatePoint(Geom::Point(0,h), SNAPSOURCE_UNDEFINED, SNAPTARGET_PAGE_CORNER)); |
962 | points->push_back(SnapCandidatePoint(Geom::Point(w,h), SNAPSOURCE_UNDEFINED, SNAPTARGET_PAGE_CORNER)); |
963 | |
964 | === modified file 'src/persp3d.cpp' |
965 | --- src/persp3d.cpp 2013-07-31 20:51:23 +0000 |
966 | +++ src/persp3d.cpp 2013-09-20 17:05:49 +0000 |
967 | @@ -24,6 +24,7 @@ |
968 | #include "desktop-handles.h" |
969 | #include <glibmm/i18n.h> |
970 | #include "verbs.h" |
971 | +#include "util/units.h" |
972 | |
973 | using Inkscape::DocumentUndo; |
974 | |
975 | @@ -168,10 +169,10 @@ |
976 | repr = xml_doc->createElement("inkscape:perspective"); |
977 | repr->setAttribute("sodipodi:type", "inkscape:persp3d"); |
978 | |
979 | - Proj::Pt2 proj_vp_x = Proj::Pt2 (0.0, document->getHeight()/2, 1.0); |
980 | + Proj::Pt2 proj_vp_x = Proj::Pt2 (0.0, document->getHeight().value("px")/2, 1.0); |
981 | Proj::Pt2 proj_vp_y = Proj::Pt2 (0.0, 1000.0, 0.0); |
982 | - Proj::Pt2 proj_vp_z = Proj::Pt2 (document->getWidth(), document->getHeight()/2, 1.0); |
983 | - Proj::Pt2 proj_origin = Proj::Pt2 (document->getWidth()/2, document->getHeight()/3, 1.0); |
984 | + Proj::Pt2 proj_vp_z = Proj::Pt2 (document->getWidth().value("px"), document->getHeight().value("px")/2, 1.0); |
985 | + Proj::Pt2 proj_origin = Proj::Pt2 (document->getWidth().value("px")/2, document->getHeight().value("px")/3, 1.0); |
986 | |
987 | if (dup) { |
988 | proj_vp_x = dup->tmat.column (Proj::X); |
989 | |
990 | === modified file 'src/rect-context.cpp' |
991 | --- src/rect-context.cpp 2013-08-30 21:35:42 +0000 |
992 | +++ src/rect-context.cpp 2013-09-20 17:05:49 +0000 |
993 | @@ -478,6 +478,7 @@ |
994 | } |
995 | |
996 | this->rect->updateRepr(); |
997 | + this->rect->doWriteTransform(this->rect->getRepr(), this->rect->transform, NULL, true); |
998 | |
999 | this->desktop->canvas->endForcedFullRedraws(); |
1000 | |
1001 | |
1002 | === modified file 'src/selection-chemistry.cpp' |
1003 | --- src/selection-chemistry.cpp 2013-09-19 02:05:00 +0000 |
1004 | +++ src/selection-chemistry.cpp 2013-09-20 17:05:49 +0000 |
1005 | @@ -2809,7 +2809,7 @@ |
1006 | } |
1007 | |
1008 | // calculate the transform to be applied to objects to move them to 0,0 |
1009 | - Geom::Point move_p = Geom::Point(0, doc->getHeight()) - *c; |
1010 | + Geom::Point move_p = Geom::Point(0, doc->getHeight().value("px")) - *c; |
1011 | move_p[Geom::Y] = -move_p[Geom::Y]; |
1012 | Geom::Affine move = Geom::Affine(Geom::Translate(move_p)); |
1013 | |
1014 | @@ -3093,7 +3093,7 @@ |
1015 | } |
1016 | |
1017 | // calculate the transform to be applied to objects to move them to 0,0 |
1018 | - Geom::Point move_p = Geom::Point(0, doc->getHeight()) - (r->min() + Geom::Point(0, r->dimensions()[Geom::Y])); |
1019 | + Geom::Point move_p = Geom::Point(0, doc->getHeight().value("px")) - (r->min() + Geom::Point(0, r->dimensions()[Geom::Y])); |
1020 | move_p[Geom::Y] = -move_p[Geom::Y]; |
1021 | Geom::Affine move = Geom::Affine(Geom::Translate(move_p)); |
1022 | |
1023 | @@ -3398,7 +3398,7 @@ |
1024 | res = prefs_res; |
1025 | } else if (0 < prefs_min) { |
1026 | // If minsize is given, look up minimum bitmap size (default 250 pixels) and calculate resolution from it |
1027 | - res = Inkscape::Util::Quantity::convert(1, "in", "px") * prefs_min / MIN(bbox->width(), bbox->height()); |
1028 | + res = Inkscape::Util::Quantity::convert(prefs_min, "in", "px") / MIN(bbox->width(), bbox->height()); |
1029 | } else { |
1030 | float hint_xdpi = 0, hint_ydpi = 0; |
1031 | Glib::ustring hint_filename; |
1032 | @@ -3419,8 +3419,8 @@ |
1033 | } |
1034 | |
1035 | // The width and height of the bitmap in pixels |
1036 | - unsigned width = (unsigned) floor(bbox->width() * res / Inkscape::Util::Quantity::convert(1, "in", "px")); |
1037 | - unsigned height =(unsigned) floor(bbox->height() * res / Inkscape::Util::Quantity::convert(1, "in", "px")); |
1038 | + unsigned width = (unsigned) floor(bbox->width() * Inkscape::Util::Quantity::convert(res, "px", "in")); |
1039 | + unsigned height =(unsigned) floor(bbox->height() * Inkscape::Util::Quantity::convert(res, "px", "in")); |
1040 | |
1041 | // Find out if we have to run an external filter |
1042 | gchar const *run = NULL; |
1043 | |
1044 | === modified file 'src/shape-editor.cpp' |
1045 | --- src/shape-editor.cpp 2013-08-03 21:39:12 +0000 |
1046 | +++ src/shape-editor.cpp 2013-09-20 17:05:49 +0000 |
1047 | @@ -35,6 +35,8 @@ |
1048 | |
1049 | using Inkscape::createKnotHolder; |
1050 | |
1051 | +bool ShapeEditor::_blockSetItem = false; |
1052 | + |
1053 | ShapeEditor::ShapeEditor(SPDesktop *dt) { |
1054 | this->desktop = dt; |
1055 | this->knotholder = NULL; |
1056 | @@ -169,6 +171,10 @@ |
1057 | |
1058 | |
1059 | void ShapeEditor::set_item(SPItem *item, SubType type, bool keep_knotholder) { |
1060 | + if (_blockSetItem) { |
1061 | + return; |
1062 | + } |
1063 | + |
1064 | // this happens (and should only happen) when for an LPEItem having both knotholder and |
1065 | // nodepath the knotholder is adapted; in this case we don't want to delete the knotholder |
1066 | // since this freezes the handles |
1067 | |
1068 | === modified file 'src/shape-editor.h' |
1069 | --- src/shape-editor.h 2011-10-05 07:06:08 +0000 |
1070 | +++ src/shape-editor.h 2013-09-20 17:05:49 +0000 |
1071 | @@ -65,11 +65,14 @@ |
1072 | void shapeeditor_event_attr_changed(gchar const *name); |
1073 | |
1074 | bool knot_mouseover(); |
1075 | + |
1076 | + static void blockSetItem(bool b) {_blockSetItem = b;} |
1077 | |
1078 | private: |
1079 | bool has_knotholder (); |
1080 | void reset_item (SubType type, bool keep_knotholder = true); |
1081 | const SPItem *get_item (SubType type); |
1082 | + static bool _blockSetItem; |
1083 | |
1084 | SPDesktop *desktop; |
1085 | KnotHolder *knotholder; |
1086 | |
1087 | === modified file 'src/sp-ellipse.cpp' |
1088 | --- src/sp-ellipse.cpp 2013-09-20 04:45:16 +0000 |
1089 | +++ src/sp-ellipse.cpp 2013-09-20 17:05:49 +0000 |
1090 | @@ -318,6 +318,59 @@ |
1091 | } |
1092 | } |
1093 | |
1094 | +Geom::Affine SPGenericEllipse::set_transform(Geom::Affine const &xform) |
1095 | +{ |
1096 | + /* Calculate ellipse start in parent coords. */ |
1097 | + Geom::Point pos( Geom::Point(this->cx.computed, this->cy.computed) * xform ); |
1098 | + |
1099 | + /* This function takes care of translation and scaling, we return whatever parts we can't |
1100 | + handle. */ |
1101 | + Geom::Affine ret(Geom::Affine(xform).withoutTranslation()); |
1102 | + gdouble const sw = hypot(ret[0], ret[1]); |
1103 | + gdouble const sh = hypot(ret[2], ret[3]); |
1104 | + if (sw > 1e-9) { |
1105 | + ret[0] /= sw; |
1106 | + ret[1] /= sw; |
1107 | + } else { |
1108 | + ret[0] = 1.0; |
1109 | + ret[1] = 0.0; |
1110 | + } |
1111 | + if (sh > 1e-9) { |
1112 | + ret[2] /= sh; |
1113 | + ret[3] /= sh; |
1114 | + } else { |
1115 | + ret[2] = 0.0; |
1116 | + ret[3] = 1.0; |
1117 | + } |
1118 | + |
1119 | + if (this->rx._set) { |
1120 | + this->rx = this->rx.computed * sw; |
1121 | + } |
1122 | + if (this->ry._set) { |
1123 | + this->ry = this->ry.computed * sh; |
1124 | + } |
1125 | + |
1126 | + /* Find start in item coords */ |
1127 | + pos = pos * ret.inverse(); |
1128 | + this->cx = pos[Geom::X]; |
1129 | + this->cy = pos[Geom::Y]; |
1130 | + |
1131 | + this->set_shape(); |
1132 | + |
1133 | + // Adjust stroke width |
1134 | + this->adjust_stroke(sqrt(fabs(sw * sh))); |
1135 | + |
1136 | + // Adjust pattern fill |
1137 | + this->adjust_pattern(xform * ret.inverse()); |
1138 | + |
1139 | + // Adjust gradient fill |
1140 | + this->adjust_gradient(xform * ret.inverse()); |
1141 | + |
1142 | + this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_STYLE_MODIFIED_FLAG); |
1143 | + |
1144 | + return ret; |
1145 | +} |
1146 | + |
1147 | void |
1148 | sp_genericellipse_normalize(SPGenericEllipse *ellipse) |
1149 | { |
1150 | |
1151 | === modified file 'src/sp-ellipse.h' |
1152 | --- src/sp-ellipse.h 2013-09-20 04:45:16 +0000 |
1153 | +++ src/sp-ellipse.h 2013-09-20 17:05:49 +0000 |
1154 | @@ -39,6 +39,7 @@ |
1155 | |
1156 | virtual void snappoints(std::vector<Inkscape::SnapCandidatePoint> &p, Inkscape::SnapPreferences const *snapprefs); |
1157 | virtual void set_shape(); |
1158 | + virtual Geom::Affine set_transform(Geom::Affine const& xform); |
1159 | |
1160 | virtual void update_patheffect(bool write); |
1161 | }; |
1162 | |
1163 | === modified file 'src/sp-flowtext.cpp' |
1164 | --- src/sp-flowtext.cpp 2013-09-20 04:45:16 +0000 |
1165 | +++ src/sp-flowtext.cpp 2013-09-20 17:05:49 +0000 |
1166 | @@ -28,6 +28,7 @@ |
1167 | #include "text-tag-attributes.h" |
1168 | #include "text-chemistry.h" |
1169 | #include "text-editing.h" |
1170 | +#include "sp-text.h" |
1171 | |
1172 | #include "livarot/Shape.h" |
1173 | |
1174 | @@ -648,6 +649,44 @@ |
1175 | return ft_item; |
1176 | } |
1177 | |
1178 | +Geom::Affine SPFlowtext::set_transform (Geom::Affine const &xform) |
1179 | +{ |
1180 | + if ((this->_optimizeScaledText && !xform.withoutTranslation().isNonzeroUniformScale()) |
1181 | + || (!this->_optimizeScaledText && !xform.isNonzeroUniformScale())) { |
1182 | + this->_optimizeScaledText = false; |
1183 | + return xform; |
1184 | + } |
1185 | + this->_optimizeScaledText = false; |
1186 | + |
1187 | + SPText *text = reinterpret_cast<SPText *>(this); |
1188 | + |
1189 | + double const ex = xform.descrim(); |
1190 | + if (ex == 0) { |
1191 | + return xform; |
1192 | + } |
1193 | + |
1194 | + Geom::Affine ret(xform); |
1195 | + ret[0] /= ex; |
1196 | + ret[1] /= ex; |
1197 | + ret[2] /= ex; |
1198 | + ret[3] /= ex; |
1199 | + |
1200 | + // Adjust font size |
1201 | + text->_adjustFontsizeRecursive (this, ex); |
1202 | + |
1203 | + // Adjust stroke width |
1204 | + this->adjust_stroke_width_recursive (ex); |
1205 | + |
1206 | + // Adjust pattern fill |
1207 | + this->adjust_pattern(xform * ret.inverse()); |
1208 | + |
1209 | + // Adjust gradient fill |
1210 | + this->adjust_gradient(xform * ret.inverse()); |
1211 | + |
1212 | + this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_TEXT_LAYOUT_MODIFIED_FLAG); |
1213 | + |
1214 | + return ret; |
1215 | +} |
1216 | |
1217 | /* |
1218 | Local Variables: |
1219 | |
1220 | === modified file 'src/sp-flowtext.h' |
1221 | --- src/sp-flowtext.h 2013-09-20 04:45:16 +0000 |
1222 | +++ src/sp-flowtext.h 2013-09-20 17:05:49 +0000 |
1223 | @@ -43,6 +43,12 @@ |
1224 | |
1225 | double par_indent; |
1226 | |
1227 | + bool _optimizeScaledText; |
1228 | + |
1229 | + /** Optimize scaled flow text on next set_transform. */ |
1230 | + void optimizeScaledText() |
1231 | + {_optimizeScaledText = true;} |
1232 | + |
1233 | private: |
1234 | /** Recursively walks the xml tree adding tags and their contents. */ |
1235 | void _buildLayoutInput(SPObject *root, Shape const *exclusion_shape, std::list<Shape> *shapes, SPObject **pending_line_break_object); |
1236 | @@ -58,6 +64,7 @@ |
1237 | virtual void remove_child(Inkscape::XML::Node* child); |
1238 | |
1239 | virtual void set(unsigned int key, const gchar* value); |
1240 | + virtual Geom::Affine set_transform(Geom::Affine const& xform); |
1241 | |
1242 | virtual void update(SPCtx* ctx, unsigned int flags); |
1243 | virtual void modified(unsigned int flags); |
1244 | |
1245 | === modified file 'src/sp-guide.cpp' |
1246 | --- src/sp-guide.cpp 2013-08-30 21:35:42 +0000 |
1247 | +++ src/sp-guide.cpp 2013-09-20 17:05:49 +0000 |
1248 | @@ -287,7 +287,7 @@ |
1249 | std::list<std::pair<Geom::Point, Geom::Point> > pts; |
1250 | |
1251 | Geom::Point A(0, 0); |
1252 | - Geom::Point C(doc->getWidth(), doc->getHeight()); |
1253 | + Geom::Point C(doc->getWidth().value("px"), doc->getHeight().value("px")); |
1254 | Geom::Point B(C[Geom::X], 0); |
1255 | Geom::Point D(0, C[Geom::Y]); |
1256 | |
1257 | |
1258 | === modified file 'src/sp-item-group.cpp' |
1259 | --- src/sp-item-group.cpp 2013-09-20 04:45:16 +0000 |
1260 | +++ src/sp-item-group.cpp 2013-09-20 17:05:49 +0000 |
1261 | @@ -50,6 +50,9 @@ |
1262 | #include "sp-switch.h" |
1263 | #include "sp-defs.h" |
1264 | #include "verbs.h" |
1265 | +#include "layer-model.h" |
1266 | +#include "sp-textpath.h" |
1267 | +#include "sp-flowtext.h" |
1268 | |
1269 | using Inkscape::DocumentUndo; |
1270 | |
1271 | @@ -644,6 +647,81 @@ |
1272 | } |
1273 | } |
1274 | |
1275 | +// Recursively scale child items around a point |
1276 | +void SPGroup::scaleChildItemsRec(Geom::Scale const &sc, Geom::Point const &p) |
1277 | +{ |
1278 | + if ( hasChildren() ) { |
1279 | + for (SPObject *o = firstChild() ; o ; o = o->getNext() ) { |
1280 | + if ( SP_IS_ITEM(o) ) { |
1281 | + if (SP_IS_GROUP(o) && !SP_IS_BOX3D(o)) { |
1282 | + SP_GROUP(o)->scaleChildItemsRec(sc, p); |
1283 | + } else { |
1284 | + SPItem *item = SP_ITEM(o); |
1285 | + Geom::OptRect bbox = item->desktopVisualBounds(); |
1286 | + if (bbox) { |
1287 | + // Scale item |
1288 | + Geom::Translate const s(p); |
1289 | + Geom::Affine final = s.inverse() * sc * s; |
1290 | + |
1291 | + Geom::Point old_center(0,0); |
1292 | + if (item->isCenterSet()) { |
1293 | + old_center = item->getCenter(); |
1294 | + } |
1295 | + |
1296 | + gchar const *conn_type = NULL; |
1297 | + if (SP_IS_TEXT_TEXTPATH(item)) { |
1298 | + SP_TEXT(item)->optimizeTextpathText(); |
1299 | + } else if (SP_IS_FLOWTEXT(item)) { |
1300 | + SP_FLOWTEXT(item)->optimizeScaledText(); |
1301 | + } else if (SP_IS_BOX3D(item)) { |
1302 | + // Force recalculation from perspective |
1303 | + box3d_position_set(SP_BOX3D(item)); |
1304 | + } else if (item->getAttribute("inkscape:connector-type") != NULL |
1305 | + && (item->getAttribute("inkscape:connection-start") == NULL |
1306 | + || item->getAttribute("inkscape:connection-end") == NULL)) { |
1307 | + // Remove and store connector type for transform if disconnected |
1308 | + conn_type = item->getAttribute("inkscape:connector-type"); |
1309 | + item->removeAttribute("inkscape:connector-type"); |
1310 | + } |
1311 | + |
1312 | + if (SP_IS_PERSP3D(item)) { |
1313 | + persp3d_apply_affine_transformation(SP_PERSP3D(item), final); |
1314 | + } else if ((SP_IS_TEXT_TEXTPATH(item) || SP_IS_FLOWTEXT(item)) && !item->transform.isIdentity()) { |
1315 | + // Save and reset current transform |
1316 | + Geom::Affine tmp(item->transform); |
1317 | + item->transform = Geom::Affine(); |
1318 | + // Apply scale |
1319 | + item->set_i2d_affine(item->i2dt_affine() * sc); |
1320 | + item->doWriteTransform(item->getRepr(), item->transform, NULL, true); |
1321 | + // Scale translation and restore original transform |
1322 | + tmp[4] *= sc[0]; |
1323 | + tmp[5] *= sc[1]; |
1324 | + item->doWriteTransform(item->getRepr(), tmp, NULL, true); |
1325 | + } else if (SP_IS_USE(item)) { |
1326 | + // calculate the matrix we need to apply to the clone |
1327 | + // to cancel its induced transform from its original |
1328 | + Geom::Affine move = final.inverse() * item->transform * final; |
1329 | + item->doWriteTransform(item->getRepr(), move, &move, true); |
1330 | + } else { |
1331 | + item->set_i2d_affine(item->i2dt_affine() * final); |
1332 | + item->doWriteTransform(item->getRepr(), item->transform, NULL, true); |
1333 | + } |
1334 | + |
1335 | + if (conn_type != NULL) { |
1336 | + item->setAttribute("inkscape:connector-type", conn_type); |
1337 | + } |
1338 | + |
1339 | + if (item->isCenterSet() && !(final.isTranslation() || final.isIdentity())) { |
1340 | + item->setCenter(old_center * final); |
1341 | + item->updateRepr(); |
1342 | + } |
1343 | + } |
1344 | + } |
1345 | + } |
1346 | + } |
1347 | + } |
1348 | +} |
1349 | + |
1350 | gint SPGroup::getItemCount() { |
1351 | gint len = 0; |
1352 | for (SPObject *o = this->firstChild() ; o ; o = o->getNext() ) { |
1353 | |
1354 | === modified file 'src/sp-item-group.h' |
1355 | --- src/sp-item-group.h 2013-09-20 04:45:16 +0000 |
1356 | +++ src/sp-item-group.h 2013-09-20 17:05:49 +0000 |
1357 | @@ -52,6 +52,7 @@ |
1358 | LayerMode layerDisplayMode(unsigned int display_key) const; |
1359 | void setLayerDisplayMode(unsigned int display_key, LayerMode mode); |
1360 | void translateChildItems(Geom::Translate const &tr); |
1361 | + void scaleChildItemsRec(Geom::Scale const &sc, Geom::Point const &p); |
1362 | |
1363 | gint getItemCount(); |
1364 | void _showChildren (Inkscape::Drawing &drawing, Inkscape::DrawingItem *ai, unsigned int key, unsigned int flags); |
1365 | |
1366 | === modified file 'src/sp-item.cpp' |
1367 | --- src/sp-item.cpp 2013-09-20 04:45:16 +0000 |
1368 | +++ src/sp-item.cpp 2013-09-20 17:05:49 +0000 |
1369 | @@ -73,6 +73,8 @@ |
1370 | #include "live_effects/effect.h" |
1371 | #include "live_effects/lpeobject-reference.h" |
1372 | |
1373 | +#include "util/units.h" |
1374 | + |
1375 | #define noSP_ITEM_DEBUG_IDLE |
1376 | |
1377 | |
1378 | @@ -818,7 +820,7 @@ |
1379 | Geom::OptRect SPItem::desktopVisualBounds() const |
1380 | { |
1381 | /// @fixme hardcoded desktop transform |
1382 | - Geom::Affine m = Geom::Scale(1, -1) * Geom::Translate(0, document->getHeight()); |
1383 | + Geom::Affine m = Geom::Scale(1, -1) * Geom::Translate(0, document->getHeight().value("px")); |
1384 | Geom::OptRect ret = documentVisualBounds(); |
1385 | if (ret) *ret *= m; |
1386 | return ret; |
1387 | @@ -1500,7 +1502,7 @@ |
1388 | // TODO temp code to prevent crashing on command-line launch: |
1389 | ret = i2doc_affine() |
1390 | * Geom::Scale(1, -1) |
1391 | - * Geom::Translate(0, document->getHeight()); |
1392 | + * Geom::Translate(0, document->getHeight().value("px")); |
1393 | } |
1394 | return ret; |
1395 | } |
1396 | |
1397 | === modified file 'src/sp-root.h' |
1398 | --- src/sp-root.h 2013-09-15 00:43:49 +0000 |
1399 | +++ src/sp-root.h 2013-09-20 17:05:49 +0000 |
1400 | @@ -41,7 +41,7 @@ |
1401 | SVGLength height; |
1402 | |
1403 | /* viewBox; */ |
1404 | - unsigned int viewBox_set : 1; |
1405 | + bool viewBox_set : true; |
1406 | Geom::Rect viewBox; |
1407 | |
1408 | /* preserveAspectRatio */ |
1409 | |
1410 | === modified file 'src/sp-spiral.cpp' |
1411 | --- src/sp-spiral.cpp 2013-09-20 04:45:16 +0000 |
1412 | +++ src/sp-spiral.cpp 2013-09-20 17:05:49 +0000 |
1413 | @@ -28,7 +28,6 @@ |
1414 | |
1415 | #include "sp-spiral.h" |
1416 | |
1417 | - |
1418 | #include "sp-factory.h" |
1419 | |
1420 | namespace { |
1421 | @@ -435,6 +434,58 @@ |
1422 | } |
1423 | |
1424 | /** |
1425 | + * Set spiral transform |
1426 | + */ |
1427 | +Geom::Affine SPSpiral::set_transform(Geom::Affine const &xform) |
1428 | +{ |
1429 | + // Only set transform with proportional scaling |
1430 | + if (!xform.withoutTranslation().isUniformScale()) { |
1431 | + return xform; |
1432 | + } |
1433 | + |
1434 | + /* Calculate spiral start in parent coords. */ |
1435 | + Geom::Point pos( Geom::Point(this->cx, this->cy) * xform ); |
1436 | + |
1437 | + /* This function takes care of translation and scaling, we return whatever parts we can't |
1438 | + handle. */ |
1439 | + Geom::Affine ret(Geom::Affine(xform).withoutTranslation()); |
1440 | + gdouble const s = hypot(ret[0], ret[1]); |
1441 | + if (s > 1e-9) { |
1442 | + ret[0] /= s; |
1443 | + ret[1] /= s; |
1444 | + ret[2] /= s; |
1445 | + ret[3] /= s; |
1446 | + } else { |
1447 | + ret[0] = 1.0; |
1448 | + ret[1] = 0.0; |
1449 | + ret[2] = 0.0; |
1450 | + ret[3] = 1.0; |
1451 | + } |
1452 | + |
1453 | + this->rad *= s; |
1454 | + |
1455 | + /* Find start in item coords */ |
1456 | + pos = pos * ret.inverse(); |
1457 | + this->cx = pos[Geom::X]; |
1458 | + this->cy = pos[Geom::Y]; |
1459 | + |
1460 | + this->set_shape(); |
1461 | + |
1462 | + // Adjust stroke width |
1463 | + this->adjust_stroke(s); |
1464 | + |
1465 | + // Adjust pattern fill |
1466 | + this->adjust_pattern(xform * ret.inverse()); |
1467 | + |
1468 | + // Adjust gradient fill |
1469 | + this->adjust_gradient(xform * ret.inverse()); |
1470 | + |
1471 | + this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_STYLE_MODIFIED_FLAG); |
1472 | + |
1473 | + return ret; |
1474 | +} |
1475 | + |
1476 | +/** |
1477 | * Return one of the points on the spiral. |
1478 | * |
1479 | * \param t specifies how far along the spiral. |
1480 | |
1481 | === modified file 'src/sp-spiral.h' |
1482 | --- src/sp-spiral.h 2013-09-20 04:45:16 +0000 |
1483 | +++ src/sp-spiral.h 2013-09-20 17:05:49 +0000 |
1484 | @@ -53,6 +53,7 @@ |
1485 | |
1486 | /* Lowlevel interface */ |
1487 | void setPosition(gdouble cx, gdouble cy, gdouble exp, gdouble revo, gdouble rad, gdouble arg, gdouble t0); |
1488 | + virtual Geom::Affine set_transform(Geom::Affine const& xform); |
1489 | |
1490 | Geom::Point getXY(gdouble t) const; |
1491 | |
1492 | |
1493 | === modified file 'src/sp-star.cpp' |
1494 | --- src/sp-star.cpp 2013-09-20 04:45:16 +0000 |
1495 | +++ src/sp-star.cpp 2013-09-20 17:05:49 +0000 |
1496 | @@ -514,6 +514,55 @@ |
1497 | } |
1498 | } |
1499 | |
1500 | +Geom::Affine SPStar::set_transform(Geom::Affine const &xform) |
1501 | +{ |
1502 | + // Only set transform with proportional scaling |
1503 | + if (!xform.withoutTranslation().isUniformScale()) { |
1504 | + return xform; |
1505 | + } |
1506 | + |
1507 | + /* Calculate star start in parent coords. */ |
1508 | + Geom::Point pos( this->center * xform ); |
1509 | + |
1510 | + /* This function takes care of translation and scaling, we return whatever parts we can't |
1511 | + handle. */ |
1512 | + Geom::Affine ret(Geom::Affine(xform).withoutTranslation()); |
1513 | + gdouble const s = hypot(ret[0], ret[1]); |
1514 | + if (s > 1e-9) { |
1515 | + ret[0] /= s; |
1516 | + ret[1] /= s; |
1517 | + ret[2] /= s; |
1518 | + ret[3] /= s; |
1519 | + } else { |
1520 | + ret[0] = 1.0; |
1521 | + ret[1] = 0.0; |
1522 | + ret[2] = 0.0; |
1523 | + ret[3] = 1.0; |
1524 | + } |
1525 | + |
1526 | + this->r[0] *= s; |
1527 | + this->r[1] *= s; |
1528 | + |
1529 | + /* Find start in item coords */ |
1530 | + pos = pos * ret.inverse(); |
1531 | + this->center = pos; |
1532 | + |
1533 | + this->set_shape(); |
1534 | + |
1535 | + // Adjust stroke width |
1536 | + this->adjust_stroke(s); |
1537 | + |
1538 | + // Adjust pattern fill |
1539 | + this->adjust_pattern(xform * ret.inverse()); |
1540 | + |
1541 | + // Adjust gradient fill |
1542 | + this->adjust_gradient(xform * ret.inverse()); |
1543 | + |
1544 | + this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_STYLE_MODIFIED_FLAG); |
1545 | + |
1546 | + return ret; |
1547 | +} |
1548 | + |
1549 | /** |
1550 | * sp_star_get_xy: Get X-Y value as item coordinate system |
1551 | * @star: star item |
1552 | |
1553 | === modified file 'src/sp-star.h' |
1554 | --- src/sp-star.h 2013-09-20 04:45:16 +0000 |
1555 | +++ src/sp-star.h 2013-09-20 17:05:49 +0000 |
1556 | @@ -56,6 +56,7 @@ |
1557 | |
1558 | virtual void update_patheffect(bool write); |
1559 | virtual void set_shape(); |
1560 | + virtual Geom::Affine set_transform(Geom::Affine const& xform); |
1561 | }; |
1562 | |
1563 | void sp_star_position_set (SPStar *star, gint sides, Geom::Point center, gdouble r1, gdouble r2, gdouble arg1, gdouble arg2, bool isflat, double rounded, double randomized); |
1564 | |
1565 | === modified file 'src/sp-text.cpp' |
1566 | --- src/sp-text.cpp 2013-09-20 04:45:16 +0000 |
1567 | +++ src/sp-text.cpp 2013-09-20 17:05:49 +0000 |
1568 | @@ -377,8 +377,13 @@ |
1569 | |
1570 | Geom::Affine SPText::set_transform(Geom::Affine const &xform) { |
1571 | // we cannot optimize textpath because changing its fontsize will break its match to the path |
1572 | - if (SP_IS_TEXT_TEXTPATH (this)) |
1573 | - return xform; |
1574 | + if (SP_IS_TEXT_TEXTPATH (this)) { |
1575 | + if (!this->_optimizeTextpathText) { |
1576 | + return xform; |
1577 | + } else { |
1578 | + this->_optimizeTextpathText = false; |
1579 | + } |
1580 | + } |
1581 | |
1582 | /* This function takes care of scaling & translation only, we return whatever parts we can't |
1583 | handle. */ |
1584 | |
1585 | === modified file 'src/sp-text.h' |
1586 | --- src/sp-text.h 2013-09-20 04:45:16 +0000 |
1587 | +++ src/sp-text.h 2013-09-20 17:05:49 +0000 |
1588 | @@ -58,6 +58,8 @@ |
1589 | /** discards the drawing objects representing this text. */ |
1590 | void _clearFlow(Inkscape::DrawingGroup *in_arena); |
1591 | |
1592 | + bool _optimizeTextpathText; |
1593 | + |
1594 | private: |
1595 | /** Recursively walks the xml tree adding tags and their contents. The |
1596 | non-trivial code does two things: firstly, it manages the positioning |
1597 | @@ -67,6 +69,10 @@ |
1598 | unsigned _buildLayoutInput(SPObject *root, Inkscape::Text::Layout::OptionalTextTagAttrs const &parent_optional_attrs, unsigned parent_attrs_offset, bool in_textpath); |
1599 | |
1600 | public: |
1601 | + /** Optimize textpath text on next set_transform. */ |
1602 | + void optimizeTextpathText() |
1603 | + {_optimizeTextpathText = true;} |
1604 | + |
1605 | virtual void build(SPDocument* doc, Inkscape::XML::Node* repr); |
1606 | virtual void release(); |
1607 | virtual void child_added(Inkscape::XML::Node* child, Inkscape::XML::Node* ref); |
1608 | |
1609 | === modified file 'src/spiral-context.cpp' |
1610 | --- src/spiral-context.cpp 2013-08-30 21:35:42 +0000 |
1611 | +++ src/spiral-context.cpp 2013-09-20 17:05:49 +0000 |
1612 | @@ -417,6 +417,7 @@ |
1613 | |
1614 | spiral->set_shape(); |
1615 | spiral->updateRepr(SP_OBJECT_WRITE_EXT); |
1616 | + spiral->doWriteTransform(spiral->getRepr(), spiral->transform, NULL, true); |
1617 | |
1618 | this->desktop->canvas->endForcedFullRedraws(); |
1619 | |
1620 | |
1621 | === modified file 'src/star-context.cpp' |
1622 | --- src/star-context.cpp 2013-08-30 21:35:42 +0000 |
1623 | +++ src/star-context.cpp 2013-09-20 17:05:49 +0000 |
1624 | @@ -443,6 +443,7 @@ |
1625 | this->star->setCenter(this->center); |
1626 | this->star->set_shape(); |
1627 | this->star->updateRepr(SP_OBJECT_WRITE_EXT); |
1628 | + this->star->doWriteTransform(this->star->getRepr(), this->star->transform, NULL, true); |
1629 | |
1630 | desktop->canvas->endForcedFullRedraws(); |
1631 | |
1632 | |
1633 | === modified file 'src/style.cpp' |
1634 | --- src/style.cpp 2013-09-18 19:16:05 +0000 |
1635 | +++ src/style.cpp 2013-09-20 17:05:49 +0000 |
1636 | @@ -2523,11 +2523,11 @@ |
1637 | |
1638 | case SP_CSS_UNIT_NONE: unit_size = size; break; |
1639 | case SP_CSS_UNIT_PX: unit_size = size; break; |
1640 | - case SP_CSS_UNIT_PT: unit_size = size * Inkscape::Util::Quantity::convert(1, "px", "pt"); break; |
1641 | - case SP_CSS_UNIT_PC: unit_size = size * (Inkscape::Util::Quantity::convert(1, "px", "pt") / Inkscape::Util::Quantity::convert(1, "pc", "pt")); break; |
1642 | - case SP_CSS_UNIT_MM: unit_size = size * Inkscape::Util::Quantity::convert(1, "px", "mm"); break; |
1643 | - case SP_CSS_UNIT_CM: unit_size = size * Inkscape::Util::Quantity::convert(1, "px", "cm"); break; |
1644 | - case SP_CSS_UNIT_IN: unit_size = size * Inkscape::Util::Quantity::convert(1, "px", "in"); break; |
1645 | + case SP_CSS_UNIT_PT: unit_size = Inkscape::Util::Quantity::convert(size, "px", "pt"); break; |
1646 | + case SP_CSS_UNIT_PC: unit_size = Inkscape::Util::Quantity::convert(size, "px", "pc"); break; |
1647 | + case SP_CSS_UNIT_MM: unit_size = Inkscape::Util::Quantity::convert(size, "px", "mm"); break; |
1648 | + case SP_CSS_UNIT_CM: unit_size = Inkscape::Util::Quantity::convert(size, "px", "cm"); break; |
1649 | + case SP_CSS_UNIT_IN: unit_size = Inkscape::Util::Quantity::convert(size, "px", "in"); break; |
1650 | case SP_CSS_UNIT_EM: unit_size = size / SP_CSS_FONT_SIZE_DEFAULT; break; |
1651 | case SP_CSS_UNIT_EX: unit_size = size * 2.0 / SP_CSS_FONT_SIZE_DEFAULT ; break; |
1652 | case SP_CSS_UNIT_PERCENT: unit_size = size * 100.0 / SP_CSS_FONT_SIZE_DEFAULT; break; |
1653 | @@ -3530,19 +3530,19 @@ |
1654 | } else if (!strcmp(e, "pt")) { |
1655 | /* Userspace / DEVICESCALE */ |
1656 | val->unit = SP_CSS_UNIT_PT; |
1657 | - val->computed = value * Inkscape::Util::Quantity::convert(1, "pt", "px"); |
1658 | + val->computed = Inkscape::Util::Quantity::convert(value, "pt", "px"); |
1659 | } else if (!strcmp(e, "pc")) { |
1660 | val->unit = SP_CSS_UNIT_PC; |
1661 | - val->computed = value * Inkscape::Util::Quantity::convert(1, "pc", "px"); |
1662 | + val->computed = Inkscape::Util::Quantity::convert(value, "pc", "px"); |
1663 | } else if (!strcmp(e, "mm")) { |
1664 | val->unit = SP_CSS_UNIT_MM; |
1665 | - val->computed = value * Inkscape::Util::Quantity::convert(1, "mm", "px"); |
1666 | + val->computed = Inkscape::Util::Quantity::convert(value, "mm", "px"); |
1667 | } else if (!strcmp(e, "cm")) { |
1668 | val->unit = SP_CSS_UNIT_CM; |
1669 | - val->computed = value * Inkscape::Util::Quantity::convert(1, "cm", "px"); |
1670 | + val->computed = Inkscape::Util::Quantity::convert(value, "cm", "px"); |
1671 | } else if (!strcmp(e, "in")) { |
1672 | val->unit = SP_CSS_UNIT_IN; |
1673 | - val->computed = value * Inkscape::Util::Quantity::convert(1, "in", "px"); |
1674 | + val->computed = Inkscape::Util::Quantity::convert(value, "in", "px"); |
1675 | } else if (!strcmp(e, "em")) { |
1676 | /* EM square */ |
1677 | val->unit = SP_CSS_UNIT_EM; |
1678 | @@ -4204,23 +4204,23 @@ |
1679 | return g_strlcpy(p, os.str().c_str(), len); |
1680 | break; |
1681 | case SP_CSS_UNIT_PT: |
1682 | - os << key << ":" << val->computed * Inkscape::Util::Quantity::convert(1, "px", "pt") << "pt;"; |
1683 | + os << key << ":" << Inkscape::Util::Quantity::convert(val->computed, "px", "pt") << "pt;"; |
1684 | return g_strlcpy(p, os.str().c_str(), len); |
1685 | break; |
1686 | case SP_CSS_UNIT_PC: |
1687 | - os << key << ":" << val->computed * Inkscape::Util::Quantity::convert(1, "px", "pt") / 12.0 << "pc;"; |
1688 | + os << key << ":" << Inkscape::Util::Quantity::convert(val->computed, "px", "pc") << "pc;"; |
1689 | return g_strlcpy(p, os.str().c_str(), len); |
1690 | break; |
1691 | case SP_CSS_UNIT_MM: |
1692 | - os << key << ":" << val->computed * Inkscape::Util::Quantity::convert(1, "px", "mm") << "mm;"; |
1693 | + os << key << ":" << Inkscape::Util::Quantity::convert(val->computed, "px", "mm") << "mm;"; |
1694 | return g_strlcpy(p, os.str().c_str(), len); |
1695 | break; |
1696 | case SP_CSS_UNIT_CM: |
1697 | - os << key << ":" << val->computed * Inkscape::Util::Quantity::convert(1, "px", "cm") << "cm;"; |
1698 | + os << key << ":" << Inkscape::Util::Quantity::convert(val->computed, "px", "cm") << "cm;"; |
1699 | return g_strlcpy(p, os.str().c_str(), len); |
1700 | break; |
1701 | case SP_CSS_UNIT_IN: |
1702 | - os << key << ":" << val->computed * Inkscape::Util::Quantity::convert(1, "px", "in") << "in;"; |
1703 | + os << key << ":" << Inkscape::Util::Quantity::convert(val->computed, "px", "in") << "in;"; |
1704 | return g_strlcpy(p, os.str().c_str(), len); |
1705 | break; |
1706 | case SP_CSS_UNIT_EM: |
1707 | |
1708 | === modified file 'src/svg-view-widget.cpp' |
1709 | --- src/svg-view-widget.cpp 2012-06-09 20:37:17 +0000 |
1710 | +++ src/svg-view-widget.cpp 2013-09-20 17:05:49 +0000 |
1711 | @@ -21,6 +21,7 @@ |
1712 | #include "document.h" |
1713 | #include "svg-view.h" |
1714 | #include "svg-view-widget.h" |
1715 | +#include "util/units.h" |
1716 | |
1717 | static void sp_svg_view_widget_class_init (SPSVGSPViewWidgetClass *klass); |
1718 | static void sp_svg_view_widget_init (SPSVGSPViewWidget *widget); |
1719 | @@ -175,8 +176,8 @@ |
1720 | gdouble width, height; |
1721 | |
1722 | svgv = static_cast<SPSVGView*> (v); |
1723 | - width = (v->doc())->getWidth () * svgv->_hscale; |
1724 | - height = (v->doc())->getHeight () * svgv->_vscale; |
1725 | + width = (v->doc())->getWidth().value("px") * svgv->_hscale; |
1726 | + height = (v->doc())->getHeight().value("px") * svgv->_vscale; |
1727 | |
1728 | if (width <= vw->maxwidth) { |
1729 | hpol = GTK_POLICY_NEVER; |
1730 | |
1731 | === modified file 'src/svg-view.cpp' |
1732 | --- src/svg-view.cpp 2012-04-09 17:19:31 +0000 |
1733 | +++ src/svg-view.cpp 2013-09-20 17:05:49 +0000 |
1734 | @@ -20,6 +20,7 @@ |
1735 | #include "sp-item.h" |
1736 | #include "svg-view.h" |
1737 | #include "sp-root.h" |
1738 | +#include "util/units.h" |
1739 | |
1740 | SPSVGView::SPSVGView(SPCanvasGroup *parent) |
1741 | { |
1742 | @@ -71,16 +72,16 @@ |
1743 | if (!doc()) { |
1744 | return; |
1745 | } |
1746 | - if (doc()->getWidth () < 1e-9) { |
1747 | + if (doc()->getWidth().value("px") < 1e-9) { |
1748 | return; |
1749 | } |
1750 | - if (doc()->getHeight () < 1e-9) { |
1751 | + if (doc()->getHeight().value("px") < 1e-9) { |
1752 | return; |
1753 | } |
1754 | |
1755 | if (_rescale) { |
1756 | - _hscale = _width / doc()->getWidth (); |
1757 | - _vscale = _height / doc()->getHeight (); |
1758 | + _hscale = _width / doc()->getWidth().value("px"); |
1759 | + _vscale = _height / doc()->getHeight().value("px"); |
1760 | if (_keepaspect) { |
1761 | if (_hscale > _vscale) { |
1762 | _hscale = _vscale; |
1763 | @@ -95,8 +96,8 @@ |
1764 | } |
1765 | |
1766 | if (event) { |
1767 | - emitResized (doc()->getWidth () * _hscale, |
1768 | - doc()->getHeight () * _vscale); |
1769 | + emitResized (doc()->getWidth().value("px") * _hscale, |
1770 | + doc()->getHeight().value("px") * _vscale); |
1771 | } |
1772 | } |
1773 | |
1774 | |
1775 | === modified file 'src/text-context.cpp' |
1776 | --- src/text-context.cpp 2013-08-30 21:35:42 +0000 |
1777 | +++ src/text-context.cpp 2013-09-20 17:05:49 +0000 |
1778 | @@ -441,6 +441,7 @@ |
1779 | text_item->transform = SP_ITEM(ec->desktop->currentLayer())->i2doc_affine().inverse(); |
1780 | |
1781 | text_item->updateRepr(); |
1782 | + text_item->doWriteTransform(text_item->getRepr(), text_item->transform, NULL, true); |
1783 | DocumentUndo::done(sp_desktop_document(ec->desktop), SP_VERB_CONTEXT_TEXT, |
1784 | _("Create text")); |
1785 | } |
1786 | |
1787 | === modified file 'src/ui/clipboard.cpp' |
1788 | --- src/ui/clipboard.cpp 2013-09-14 11:09:15 +0000 |
1789 | +++ src/ui/clipboard.cpp 2013-09-20 17:05:49 +0000 |
1790 | @@ -1087,8 +1087,8 @@ |
1791 | Geom::Point origin (_clipboardSPDoc->getRoot()->x.computed, _clipboardSPDoc->getRoot()->y.computed); |
1792 | Geom::Rect area = Geom::Rect(origin, origin + _clipboardSPDoc->getDimensions()); |
1793 | |
1794 | - unsigned long int width = (unsigned long int) (area.width() * dpi / Inkscape::Util::Quantity::convert(1, "in", "px") + 0.5); |
1795 | - unsigned long int height = (unsigned long int) (area.height() * dpi / Inkscape::Util::Quantity::convert(1, "in", "px") + 0.5); |
1796 | + unsigned long int width = (unsigned long int) (Inkscape::Util::Quantity::convert(area.width(), "px", "in") * dpi + 0.5); |
1797 | + unsigned long int height = (unsigned long int) (Inkscape::Util::Quantity::convert(area.height(), "in", "px") * dpi + 0.5); |
1798 | |
1799 | // read from namedview |
1800 | Inkscape::XML::Node *nv = sp_repr_lookup_name (_clipboardSPDoc->rroot, "sodipodi:namedview"); |
1801 | |
1802 | === modified file 'src/ui/dialog/aboutbox.cpp' |
1803 | --- src/ui/dialog/aboutbox.cpp 2013-06-17 22:53:50 +0000 |
1804 | +++ src/ui/dialog/aboutbox.cpp 2013-09-20 17:05:49 +0000 |
1805 | @@ -34,6 +34,7 @@ |
1806 | #include "svg-view-widget.h" |
1807 | #include "sp-text.h" |
1808 | #include "text-editing.h" |
1809 | +#include "util/units.h" |
1810 | |
1811 | #include "inkscape-version.h" |
1812 | |
1813 | @@ -175,8 +176,8 @@ |
1814 | |
1815 | GtkWidget *v=sp_svg_view_widget_new(doc); |
1816 | |
1817 | - double width=doc->getWidth(); |
1818 | - double height=doc->getHeight(); |
1819 | + double width=doc->getWidth().value("px"); |
1820 | + double height=doc->getHeight().value("px"); |
1821 | |
1822 | doc->doUnref(); |
1823 | |
1824 | |
1825 | === modified file 'src/ui/dialog/document-properties.cpp' |
1826 | --- src/ui/dialog/document-properties.cpp 2013-08-30 21:35:42 +0000 |
1827 | +++ src/ui/dialog/document-properties.cpp 2013-09-20 17:05:49 +0000 |
1828 | @@ -31,9 +31,12 @@ |
1829 | #include "inkscape.h" |
1830 | #include "io/sys.h" |
1831 | #include "preferences.h" |
1832 | +#include "shape-editor.h" |
1833 | #include "sp-namedview.h" |
1834 | #include "sp-root.h" |
1835 | #include "sp-script.h" |
1836 | +#include "svg/stringstream.h" |
1837 | +#include "tools-switch.h" |
1838 | #include "ui/widget/color-picker.h" |
1839 | #include "ui/widget/scalar-unit.h" |
1840 | #include "ui/dialog/filedialog.h" |
1841 | @@ -53,6 +56,8 @@ |
1842 | #include <gtkmm/stock.h> |
1843 | #include <gtkmm/table.h> |
1844 | |
1845 | +#include <2geom/transforms.h> |
1846 | + |
1847 | using std::pair; |
1848 | |
1849 | namespace Inkscape { |
1850 | @@ -168,6 +173,9 @@ |
1851 | signalDocumentReplaced().connect(sigc::mem_fun(*this, &DocumentProperties::_handleDocumentReplaced)); |
1852 | signalActivateDesktop().connect(sigc::mem_fun(*this, &DocumentProperties::_handleActivateDesktop)); |
1853 | signalDeactiveDesktop().connect(sigc::mem_fun(*this, &DocumentProperties::_handleDeactivateDesktop)); |
1854 | + |
1855 | + _rum_deflt._changed_connection.block(); |
1856 | + _rum_deflt.getUnitMenu()->signal_changed().connect(sigc::mem_fun(*this, &DocumentProperties::onDocUnitChange)); |
1857 | } |
1858 | |
1859 | void DocumentProperties::init() |
1860 | @@ -1432,9 +1440,17 @@ |
1861 | if (nv->doc_units) |
1862 | _rum_deflt.setUnit (nv->doc_units->abbr); |
1863 | |
1864 | - double const doc_w_px = sp_desktop_document(dt)->getWidth(); |
1865 | - double const doc_h_px = sp_desktop_document(dt)->getHeight(); |
1866 | - _page_sizer.setDim (doc_w_px, doc_h_px); |
1867 | + double const doc_w = sp_desktop_document(dt)->getRoot()->width.value; |
1868 | + Glib::ustring doc_w_unit = unit_table.getUnit(sp_desktop_document(dt)->getRoot()->width.unit).abbr; |
1869 | + if (doc_w_unit == "") { |
1870 | + doc_w_unit = "px"; |
1871 | + } |
1872 | + double const doc_h = sp_desktop_document(dt)->getRoot()->height.value; |
1873 | + Glib::ustring doc_h_unit = unit_table.getUnit(sp_desktop_document(dt)->getRoot()->height.unit).abbr; |
1874 | + if (doc_h_unit == "") { |
1875 | + doc_h_unit = "px"; |
1876 | + } |
1877 | + _page_sizer.setDim(Inkscape::Util::Quantity(doc_w, doc_w_unit), Inkscape::Util::Quantity(doc_h, doc_h_unit)); |
1878 | _page_sizer.updateFitMarginsUI(nv->getRepr()); |
1879 | |
1880 | //-----------------------------------------------------------guide page |
1881 | @@ -1617,6 +1633,47 @@ |
1882 | } |
1883 | } |
1884 | |
1885 | +/** Callback for document unit change. */ |
1886 | +void DocumentProperties::onDocUnitChange() |
1887 | +{ |
1888 | + SPDocument *doc = SP_ACTIVE_DOCUMENT; |
1889 | + Inkscape::XML::Node *repr = sp_desktop_namedview(getDesktop())->getRepr(); |
1890 | + Inkscape::Util::Unit old_doc_unit = unit_table.getUnit("px"); |
1891 | + if(repr->attribute("inkscape:document-units")) { |
1892 | + old_doc_unit = unit_table.getUnit(repr->attribute("inkscape:document-units")); |
1893 | + } |
1894 | + Inkscape::Util::Unit doc_unit = _rum_deflt.getUnit(); |
1895 | + |
1896 | + // Don't execute when change is being undone |
1897 | + if (!DocumentUndo::getUndoSensitive(doc)) { |
1898 | + return; |
1899 | + } |
1900 | + |
1901 | + // Set document unit |
1902 | + Inkscape::SVGOStringStream os; |
1903 | + os << doc_unit.abbr; |
1904 | + repr->setAttribute("inkscape:document-units", os.str().c_str()); |
1905 | + |
1906 | + // Set viewBox |
1907 | + Inkscape::Util::Quantity width = doc->getWidth(); |
1908 | + Inkscape::Util::Quantity height = doc->getHeight(); |
1909 | + doc->setViewBox(Geom::Rect::from_xywh(0, 0, width.value(doc_unit), height.value(doc_unit))); |
1910 | + |
1911 | + // TODO: Fix bug in nodes tool instead of switching away from it |
1912 | + if (tools_active(getDesktop()) == TOOLS_NODES) { |
1913 | + tools_switch(getDesktop(), TOOLS_SELECT); |
1914 | + } |
1915 | + |
1916 | + // Scale and translate objects |
1917 | + gdouble scale = Inkscape::Util::Quantity::convert(1, old_doc_unit, doc_unit); |
1918 | + ShapeEditor::blockSetItem(true); |
1919 | + doc->getRoot()->scaleChildItemsRec(Geom::Scale(scale), Geom::Point(0, doc->getHeight().value("px"))); |
1920 | + ShapeEditor::blockSetItem(false); |
1921 | + |
1922 | + doc->setModifiedSinceSave(); |
1923 | + |
1924 | + DocumentUndo::done(doc, SP_VERB_NONE, _("Changed document unit")); |
1925 | +} |
1926 | |
1927 | } // namespace Dialog |
1928 | } // namespace UI |
1929 | |
1930 | === modified file 'src/ui/dialog/document-properties.h' |
1931 | --- src/ui/dialog/document-properties.h 2013-03-12 12:20:04 +0000 |
1932 | +++ src/ui/dialog/document-properties.h 2013-09-20 17:05:49 +0000 |
1933 | @@ -216,6 +216,9 @@ |
1934 | // callback methods for buttons on grids page. |
1935 | void onNewGrid(); |
1936 | void onRemoveGrid(); |
1937 | + |
1938 | + // callback for document unit change |
1939 | + void onDocUnitChange(); |
1940 | }; |
1941 | |
1942 | } // namespace Dialog |
1943 | |
1944 | === modified file 'src/ui/dialog/export.cpp' |
1945 | --- src/ui/dialog/export.cpp 2013-09-01 16:46:33 +0000 |
1946 | +++ src/ui/dialog/export.cpp 2013-09-20 17:05:49 +0000 |
1947 | @@ -762,7 +762,7 @@ |
1948 | } |
1949 | case SELECTION_PAGE: |
1950 | bbox = Geom::Rect(Geom::Point(0.0, 0.0), |
1951 | - Geom::Point(doc->getWidth(), doc->getHeight())); |
1952 | + Geom::Point(doc->getWidth().value("px"), doc->getHeight().value("px"))); |
1953 | |
1954 | // std::cout << "Using selection: PAGE" << std::endl; |
1955 | key = SELECTION_PAGE; |
1956 | @@ -1475,8 +1475,8 @@ |
1957 | doc = sp_desktop_document (SP_ACTIVE_DESKTOP); |
1958 | |
1959 | Geom::Point x(0.0, 0.0); |
1960 | - Geom::Point y(doc->getWidth(), |
1961 | - doc->getHeight()); |
1962 | + Geom::Point y(doc->getWidth().value("px"), |
1963 | + doc->getHeight().value("px")); |
1964 | Geom::Rect bbox(x, y); |
1965 | |
1966 | if (bbox_equal(bbox,current_bbox)) { |
1967 | |
1968 | === modified file 'src/ui/dialog/print.cpp' |
1969 | --- src/ui/dialog/print.cpp 2013-07-31 22:33:03 +0000 |
1970 | +++ src/ui/dialog/print.cpp 2013-09-20 17:05:49 +0000 |
1971 | @@ -49,8 +49,8 @@ |
1972 | |
1973 | if (junk->_tab->as_bitmap()) { |
1974 | // Render as exported PNG |
1975 | - gdouble width = (junk->_doc)->getWidth(); |
1976 | - gdouble height = (junk->_doc)->getHeight(); |
1977 | + gdouble width = (junk->_doc)->getWidth().value("px"); |
1978 | + gdouble height = (junk->_doc)->getHeight().value("px"); |
1979 | gdouble dpi = junk->_tab->bitmap_dpi(); |
1980 | std::string tmp_png; |
1981 | std::string tmp_base = "inkscape-print-png-XXXXXX"; |
1982 | @@ -72,8 +72,8 @@ |
1983 | |
1984 | sp_export_png_file(junk->_doc, tmp_png.c_str(), 0.0, 0.0, |
1985 | width, height, |
1986 | - (unsigned long)(width * dpi / Inkscape::Util::Quantity::convert(1, "in", "px")), |
1987 | - (unsigned long)(height * dpi / Inkscape::Util::Quantity::convert(1, "in", "px")), |
1988 | + (unsigned long)(Inkscape::Util::Quantity::convert(width, "px", "in") * dpi), |
1989 | + (unsigned long)(Inkscape::Util::Quantity::convert(height, "px", "in") * dpi), |
1990 | dpi, dpi, bgcolor, NULL, NULL, true, NULL); |
1991 | |
1992 | // This doesn't seem to work: |
1993 | @@ -195,8 +195,8 @@ |
1994 | // set up paper size to match the document size |
1995 | gtk_print_operation_set_unit (_printop, GTK_UNIT_POINTS); |
1996 | GtkPageSetup *page_setup = gtk_page_setup_new(); |
1997 | - gdouble doc_width = _doc->getWidth() * Inkscape::Util::Quantity::convert(1, "px", "pt"); |
1998 | - gdouble doc_height = _doc->getHeight() * Inkscape::Util::Quantity::convert(1, "px", "pt"); |
1999 | + gdouble doc_width = _doc->getWidth().value("pt"); |
2000 | + gdouble doc_height = _doc->getHeight().value("pt"); |
2001 | GtkPaperSize *paper_size; |
2002 | if (doc_width > doc_height) { |
2003 | gtk_page_setup_set_orientation (page_setup, GTK_PAGE_ORIENTATION_LANDSCAPE); |
2004 | |
2005 | === modified file 'src/ui/dialog/text-edit.cpp' |
2006 | --- src/ui/dialog/text-edit.cpp 2013-07-31 22:33:03 +0000 |
2007 | +++ src/ui/dialog/text-edit.cpp 2013-09-20 17:05:49 +0000 |
2008 | @@ -401,7 +401,7 @@ |
2009 | |
2010 | Inkscape::Preferences *prefs = Inkscape::Preferences::get(); |
2011 | int unit = prefs->getInt("/options/font/unitType", SP_CSS_UNIT_PT); |
2012 | - double pt_size = sp_style_css_size_units_to_px(sp_font_selector_get_size(fsel), unit) * Inkscape::Util::Quantity::convert(1, "px", "pt"); |
2013 | + double pt_size = Inkscape::Util::Quantity::convert(sp_style_css_size_units_to_px(sp_font_selector_get_size(fsel), unit), "px", "pt"); |
2014 | |
2015 | // Pango font size is in 1024ths of a point |
2016 | // C++11: Glib::ustring size = std::to_string( pt_size * PANGO_SCALE ); |
2017 | |
2018 | === modified file 'src/ui/widget/page-sizer.cpp' |
2019 | --- src/ui/widget/page-sizer.cpp 2013-08-06 18:44:23 +0000 |
2020 | +++ src/ui/widget/page-sizer.cpp 2013-09-20 17:05:49 +0000 |
2021 | @@ -442,6 +442,7 @@ |
2022 | _portrait_connection = _portraitButton.signal_toggled().connect (sigc::mem_fun (*this, &PageSizer::on_portrait)); |
2023 | _changedw_connection = _dimensionWidth.signal_value_changed().connect (sigc::mem_fun (*this, &PageSizer::on_value_changed)); |
2024 | _changedh_connection = _dimensionHeight.signal_value_changed().connect (sigc::mem_fun (*this, &PageSizer::on_value_changed)); |
2025 | + _changedu_connection = _dimensionUnits.getUnitMenu()->signal_changed().connect (sigc::mem_fun (*this, &PageSizer::on_units_changed)); |
2026 | _fitPageButton.signal_clicked().connect(sigc::mem_fun(*this, &PageSizer::fire_fit_canvas_to_selection_or_drawing)); |
2027 | |
2028 | show_all_children(); |
2029 | @@ -454,11 +455,11 @@ |
2030 | * 'changeList' is true, then adjust the paperSizeList to show the closest |
2031 | * standard page size. |
2032 | * |
2033 | - * \param w, h given in px |
2034 | + * \param w, h |
2035 | * \param changeList whether to modify the paper size list |
2036 | */ |
2037 | void |
2038 | -PageSizer::setDim (double w, double h, bool changeList) |
2039 | +PageSizer::setDim (Inkscape::Util::Quantity w, Inkscape::Util::Quantity h, bool changeList) |
2040 | { |
2041 | static bool _called = false; |
2042 | if (_called) { |
2043 | @@ -475,12 +476,12 @@ |
2044 | |
2045 | if (SP_ACTIVE_DESKTOP && !_widgetRegistry->isUpdating()) { |
2046 | SPDocument *doc = sp_desktop_document(SP_ACTIVE_DESKTOP); |
2047 | - double const old_height = doc->getHeight(); |
2048 | - doc->setWidth (Inkscape::Util::Quantity(w, "px")); |
2049 | - doc->setHeight (Inkscape::Util::Quantity(h, "px")); |
2050 | + Inkscape::Util::Quantity const old_height = doc->getHeight(); |
2051 | + doc->setWidth (w); |
2052 | + doc->setHeight (h); |
2053 | // The origin for the user is in the lower left corner; this point should remain stationary when |
2054 | // changing the page size. The SVG's origin however is in the upper left corner, so we must compensate for this |
2055 | - Geom::Translate const vert_offset(Geom::Point(0, (old_height - h))); |
2056 | + Geom::Translate const vert_offset(Geom::Point(0, (old_height.value("px") - h.value("px")))); |
2057 | doc->getRoot()->translateChildItems(vert_offset); |
2058 | DocumentUndo::done(doc, SP_VERB_NONE, _("Set page size")); |
2059 | } |
2060 | @@ -503,9 +504,10 @@ |
2061 | _paperSizeListSelection->select(row); |
2062 | } |
2063 | |
2064 | - Unit const& unit = _dimensionUnits.getUnit(); |
2065 | - _dimensionWidth.setValue (w / unit.factor); |
2066 | - _dimensionHeight.setValue (h / unit.factor); |
2067 | + _dimensionWidth.setUnit(w.unit->abbr); |
2068 | + _dimensionWidth.setValue (w.quantity); |
2069 | + _dimensionHeight.setUnit(h.unit->abbr); |
2070 | + _dimensionHeight.setValue (h.quantity); |
2071 | |
2072 | _paper_size_list_connection.unblock(); |
2073 | _landscape_connection.unblock(); |
2074 | @@ -547,12 +549,12 @@ |
2075 | * paperSizeListStore->children().end() if no such paper exists. |
2076 | */ |
2077 | Gtk::ListStore::iterator |
2078 | -PageSizer::find_paper_size (double w, double h) const |
2079 | +PageSizer::find_paper_size (Inkscape::Util::Quantity w, Inkscape::Util::Quantity h) const |
2080 | { |
2081 | - double smaller = w; |
2082 | - double larger = h; |
2083 | + double smaller = w.quantity; |
2084 | + double larger = h.quantity; |
2085 | if ( h < w ) { |
2086 | - smaller = h; larger = w; |
2087 | + smaller = h.quantity; larger = w.quantity; |
2088 | } |
2089 | |
2090 | g_return_val_if_fail(smaller <= larger, _paperSizeListStore->children().end()); |
2091 | @@ -562,8 +564,8 @@ |
2092 | iter != _paperSizeTable.end() ; ++iter) { |
2093 | PaperSize paper = iter->second; |
2094 | Inkscape::Util::Unit const &i_unit = paper.unit; |
2095 | - double smallX = Inkscape::Util::Quantity::convert(paper.smaller, i_unit, "px"); |
2096 | - double largeX = Inkscape::Util::Quantity::convert(paper.larger, i_unit, "px"); |
2097 | + double smallX = Inkscape::Util::Quantity::convert(paper.smaller, i_unit, *w.unit); |
2098 | + double largeX = Inkscape::Util::Quantity::convert(paper.larger, i_unit, *w.unit); |
2099 | |
2100 | g_return_val_if_fail(smallX <= largeX, _paperSizeListStore->children().end()); |
2101 | |
2102 | @@ -643,8 +645,8 @@ |
2103 | return; |
2104 | } |
2105 | PaperSize paper = piter->second; |
2106 | - double w = paper.smaller; |
2107 | - double h = paper.larger; |
2108 | + Inkscape::Util::Quantity w = Inkscape::Util::Quantity(paper.smaller, paper.unit); |
2109 | + Inkscape::Util::Quantity h = Inkscape::Util::Quantity(paper.larger, paper.unit); |
2110 | |
2111 | if (std::find(lscape_papers.begin(), lscape_papers.end(), paper.name.c_str()) != lscape_papers.end()) { |
2112 | // enforce landscape mode if this is desired for the given page format |
2113 | @@ -654,9 +656,6 @@ |
2114 | _landscape = _landscapeButton.get_active(); |
2115 | } |
2116 | |
2117 | - w = Inkscape::Util::Quantity::convert(w, paper.unit, "px"); |
2118 | - h = Inkscape::Util::Quantity::convert(h, paper.unit, "px"); |
2119 | - |
2120 | if (_landscape) |
2121 | setDim (h, w, false); |
2122 | else |
2123 | @@ -673,8 +672,8 @@ |
2124 | { |
2125 | if (!_portraitButton.get_active()) |
2126 | return; |
2127 | - double w = _dimensionWidth.getValue ("px"); |
2128 | - double h = _dimensionHeight.getValue ("px"); |
2129 | + Inkscape::Util::Quantity w = Inkscape::Util::Quantity(_dimensionWidth.getValue(""), _dimensionWidth.getUnit()); |
2130 | + Inkscape::Util::Quantity h = Inkscape::Util::Quantity(_dimensionHeight.getValue(""), _dimensionHeight.getUnit()); |
2131 | if (h < w) { |
2132 | setDim (h, w); |
2133 | } |
2134 | @@ -689,8 +688,8 @@ |
2135 | { |
2136 | if (!_landscapeButton.get_active()) |
2137 | return; |
2138 | - double w = _dimensionWidth.getValue ("px"); |
2139 | - double h = _dimensionHeight.getValue ("px"); |
2140 | + Inkscape::Util::Quantity w = Inkscape::Util::Quantity(_dimensionWidth.getValue(""), _dimensionWidth.getUnit()); |
2141 | + Inkscape::Util::Quantity h = Inkscape::Util::Quantity(_dimensionHeight.getValue(""), _dimensionHeight.getUnit()); |
2142 | if (w < h) { |
2143 | setDim (h, w); |
2144 | } |
2145 | @@ -703,11 +702,18 @@ |
2146 | PageSizer::on_value_changed() |
2147 | { |
2148 | if (_widgetRegistry->isUpdating()) return; |
2149 | - |
2150 | - setDim (_dimensionWidth.getValue("px"), |
2151 | - _dimensionHeight.getValue("px")); |
2152 | -} |
2153 | - |
2154 | + if (_unit != _dimensionUnits.getUnit().abbr) return; |
2155 | + setDim (Inkscape::Util::Quantity(_dimensionWidth.getValue(""), _dimensionUnits.getUnit()), |
2156 | + Inkscape::Util::Quantity(_dimensionHeight.getValue(""), _dimensionUnits.getUnit())); |
2157 | +} |
2158 | +void |
2159 | +PageSizer::on_units_changed() |
2160 | +{ |
2161 | + if (_widgetRegistry->isUpdating()) return; |
2162 | + _unit = _dimensionUnits.getUnit().abbr; |
2163 | + setDim (Inkscape::Util::Quantity(_dimensionWidth.getValue(""), _dimensionUnits.getUnit()), |
2164 | + Inkscape::Util::Quantity(_dimensionHeight.getValue(""), _dimensionUnits.getUnit())); |
2165 | +} |
2166 | |
2167 | } // namespace Widget |
2168 | } // namespace UI |
2169 | |
2170 | === modified file 'src/ui/widget/page-sizer.h' |
2171 | --- src/ui/widget/page-sizer.h 2013-08-04 22:01:18 +0000 |
2172 | +++ src/ui/widget/page-sizer.h 2013-09-20 17:05:49 +0000 |
2173 | @@ -161,7 +161,7 @@ |
2174 | * Set the page size to the given dimensions. If 'changeList' is |
2175 | * true, then reset the paper size list to the closest match |
2176 | */ |
2177 | - void setDim (double w, double h, bool changeList=true); |
2178 | + void setDim (Inkscape::Util::Quantity w, Inkscape::Util::Quantity h, bool changeList=true); |
2179 | |
2180 | /** |
2181 | * Updates the scalar widgets for the fit margins. (Just changes the value |
2182 | @@ -179,7 +179,7 @@ |
2183 | /** |
2184 | * Find the closest standard paper size in the table, to the |
2185 | */ |
2186 | - Gtk::ListStore::iterator find_paper_size (double w, double h) const; |
2187 | + Gtk::ListStore::iterator find_paper_size (Inkscape::Util::Quantity w, Inkscape::Util::Quantity h) const; |
2188 | |
2189 | void fire_fit_canvas_to_selection_or_drawing(); |
2190 | |
2191 | @@ -252,13 +252,17 @@ |
2192 | |
2193 | //callback |
2194 | void on_value_changed(); |
2195 | + void on_units_changed(); |
2196 | sigc::connection _changedw_connection; |
2197 | sigc::connection _changedh_connection; |
2198 | + sigc::connection _changedu_connection; |
2199 | |
2200 | Registry *_widgetRegistry; |
2201 | |
2202 | //### state - whether we are currently landscape or portrait |
2203 | bool _landscape; |
2204 | + |
2205 | + Glib::ustring _unit; |
2206 | |
2207 | }; |
2208 | |
2209 | |
2210 | === modified file 'src/ui/widget/spinbutton.cpp' |
2211 | --- src/ui/widget/spinbutton.cpp 2012-07-05 21:39:08 +0000 |
2212 | +++ src/ui/widget/spinbutton.cpp 2013-09-20 17:05:49 +0000 |
2213 | @@ -14,6 +14,7 @@ |
2214 | #include "spinbutton.h" |
2215 | |
2216 | #include "unit-menu.h" |
2217 | +#include "unit-tracker.h" |
2218 | #include "util/expression-evaluator.h" |
2219 | #include "event-context.h" |
2220 | |
2221 | @@ -32,16 +33,23 @@ |
2222 | int SpinButton::on_input(double* newvalue) |
2223 | { |
2224 | try { |
2225 | - Inkscape::Util::GimpEevlQuantity result; |
2226 | - if (_unit_menu) { |
2227 | - Unit unit = _unit_menu->getUnit(); |
2228 | - result = Inkscape::Util::gimp_eevl_evaluate (get_text().c_str(), &unit); |
2229 | + Inkscape::Util::EvaluatorQuantity result; |
2230 | + if (_unit_menu || _unit_tracker) { |
2231 | + Unit unit; |
2232 | + if (_unit_menu) { |
2233 | + unit = _unit_menu->getUnit(); |
2234 | + } else { |
2235 | + unit = _unit_tracker->getActiveUnit(); |
2236 | + } |
2237 | + Inkscape::Util::ExpressionEvaluator eval = Inkscape::Util::ExpressionEvaluator(get_text().c_str(), &unit); |
2238 | + result = eval.evaluate(); |
2239 | // check if output dimension corresponds to input unit |
2240 | if (result.dimension != (unit.isAbsolute() ? 1 : 0) ) { |
2241 | throw Inkscape::Util::EvaluatorException("Input dimensions do not match with parameter dimensions.",""); |
2242 | } |
2243 | } else { |
2244 | - result = Inkscape::Util::gimp_eevl_evaluate (get_text().c_str(), NULL); |
2245 | + Inkscape::Util::ExpressionEvaluator eval = Inkscape::Util::ExpressionEvaluator(get_text().c_str(), NULL); |
2246 | + result = eval.evaluate(); |
2247 | } |
2248 | |
2249 | *newvalue = result.value; |
2250 | |
2251 | === modified file 'src/ui/widget/spinbutton.h' |
2252 | --- src/ui/widget/spinbutton.h 2013-06-07 03:18:19 +0000 |
2253 | +++ src/ui/widget/spinbutton.h 2013-09-20 17:05:49 +0000 |
2254 | @@ -25,6 +25,7 @@ |
2255 | namespace Widget { |
2256 | |
2257 | class UnitMenu; |
2258 | +class UnitTracker; |
2259 | |
2260 | /** |
2261 | * SpinButton widget, that allows entry of simple math expressions (also units, when linked with UnitMenu), |
2262 | @@ -50,14 +51,18 @@ |
2263 | _unit_menu(NULL) |
2264 | { |
2265 | connect_signals(); |
2266 | + _unit_tracker = NULL; |
2267 | }; |
2268 | |
2269 | virtual ~SpinButton() {}; |
2270 | |
2271 | void setUnitMenu(UnitMenu* unit_menu) { _unit_menu = unit_menu; }; |
2272 | + |
2273 | + void addUnitTracker(UnitTracker* ut) { _unit_tracker = ut; }; |
2274 | |
2275 | protected: |
2276 | UnitMenu *_unit_menu; /// Linked unit menu for unit conversion in entered expressions. |
2277 | + UnitTracker *_unit_tracker; // Linked unit tracker for unit conversion in entered expressions. |
2278 | |
2279 | void connect_signals(); |
2280 | |
2281 | |
2282 | === modified file 'src/util/expression-evaluator.cpp' |
2283 | --- src/util/expression-evaluator.cpp 2013-08-04 22:01:18 +0000 |
2284 | +++ src/util/expression-evaluator.cpp 2013-09-20 17:05:49 +0000 |
2285 | @@ -6,6 +6,7 @@ |
2286 | * Copyright (C) 2008 Martin Nordholts <martinn@svn.gnome.org> |
2287 | * Modified for Inkscape by Johan Engelen |
2288 | * Copyright (C) 2011 Johan Engelen |
2289 | + * Copyright (C) 2013 Matthew Petroff |
2290 | * |
2291 | * This library is free software: you can redistribute it and/or |
2292 | * modify it under the terms of the GNU Lesser General Public |
2293 | @@ -27,6 +28,7 @@ |
2294 | #include "util/expression-evaluator.h" |
2295 | #include "util/units.h" |
2296 | |
2297 | +#include <math.h> |
2298 | #include <string.h> |
2299 | |
2300 | using Inkscape::Util::unit_table; |
2301 | @@ -34,495 +36,353 @@ |
2302 | namespace Inkscape { |
2303 | namespace Util { |
2304 | |
2305 | -enum |
2306 | -{ |
2307 | - GIMP_EEVL_TOKEN_NUM = 30000, |
2308 | - GIMP_EEVL_TOKEN_IDENTIFIER = 30001, |
2309 | - |
2310 | - GIMP_EEVL_TOKEN_ANY = 40000, |
2311 | - |
2312 | - GIMP_EEVL_TOKEN_END = 50000 |
2313 | -}; |
2314 | - |
2315 | -typedef int GimpEevlTokenType; |
2316 | - |
2317 | - |
2318 | -typedef struct |
2319 | -{ |
2320 | - GimpEevlTokenType type; |
2321 | - |
2322 | - union |
2323 | - { |
2324 | - gdouble fl; |
2325 | - |
2326 | - struct |
2327 | - { |
2328 | - const gchar *c; |
2329 | - gint size; |
2330 | - }; |
2331 | - |
2332 | - } value; |
2333 | - |
2334 | -} GimpEevlToken; |
2335 | - |
2336 | -typedef struct |
2337 | -{ |
2338 | - const gchar *string; |
2339 | - GimpEevlUnitResolverProc unit_resolver_proc; |
2340 | - Unit *unit; |
2341 | - |
2342 | - GimpEevlToken current_token; |
2343 | - const gchar *start_of_current_token; |
2344 | -} GimpEevl; |
2345 | - |
2346 | -/** Unit Resolver... |
2347 | - */ |
2348 | -static bool unitresolverproc (const gchar* identifier, GimpEevlQuantity *result, Unit* unit) |
2349 | -{ |
2350 | - if (!unit) { |
2351 | - result->value = 1; |
2352 | - result->dimension = 1; |
2353 | - return true; |
2354 | - }else if (!identifier) { |
2355 | - result->value = 1; |
2356 | - result->dimension = unit->isAbsolute() ? 1 : 0; |
2357 | - return true; |
2358 | - } else if (unit_table.hasUnit(identifier)) { |
2359 | - Unit identifier_unit = unit_table.getUnit(identifier); |
2360 | - |
2361 | - // Catch the case of zero or negative unit factors (error!) |
2362 | - if (identifier_unit.factor < 0.0000001) { |
2363 | - return false; |
2364 | - } |
2365 | - |
2366 | - result->value = unit->factor / identifier_unit.factor; |
2367 | - result->dimension = identifier_unit.isAbsolute() ? 1 : 0; |
2368 | - return true; |
2369 | - } else { |
2370 | - return false; |
2371 | - } |
2372 | -} |
2373 | - |
2374 | -static void gimp_eevl_init (GimpEevl *eva, |
2375 | - const gchar *string, |
2376 | - GimpEevlUnitResolverProc unit_resolver_proc, |
2377 | - Unit *unit); |
2378 | -static GimpEevlQuantity gimp_eevl_complete (GimpEevl *eva); |
2379 | -static GimpEevlQuantity gimp_eevl_expression (GimpEevl *eva); |
2380 | -static GimpEevlQuantity gimp_eevl_term (GimpEevl *eva); |
2381 | -static GimpEevlQuantity gimp_eevl_signed_factor (GimpEevl *eva); |
2382 | -static GimpEevlQuantity gimp_eevl_factor (GimpEevl *eva); |
2383 | -static gboolean gimp_eevl_accept (GimpEevl *eva, |
2384 | - GimpEevlTokenType token_type, |
2385 | - GimpEevlToken *consumed_token); |
2386 | -static void gimp_eevl_lex (GimpEevl *eva); |
2387 | -static void gimp_eevl_lex_accept_count (GimpEevl *eva, |
2388 | - gint count, |
2389 | - GimpEevlTokenType token_type); |
2390 | -static void gimp_eevl_lex_accept_to (GimpEevl *eva, |
2391 | - gchar *to, |
2392 | - GimpEevlTokenType token_type); |
2393 | -static void gimp_eevl_move_past_whitespace (GimpEevl *eva); |
2394 | -static gboolean gimp_eevl_unit_identifier_start (gunichar c); |
2395 | -static gboolean gimp_eevl_unit_identifier_continue (gunichar c); |
2396 | -static gint gimp_eevl_unit_identifier_size (const gchar *s, |
2397 | - gint start); |
2398 | -static void gimp_eevl_expect (GimpEevl *eva, |
2399 | - GimpEevlTokenType token_type, |
2400 | - GimpEevlToken *value); |
2401 | -static void gimp_eevl_error (GimpEevl *eva, |
2402 | - const char *msg); |
2403 | - |
2404 | +EvaluatorQuantity::EvaluatorQuantity(double value, unsigned int dimension) : |
2405 | + value(value), |
2406 | + dimension(dimension) |
2407 | +{ |
2408 | +} |
2409 | + |
2410 | +EvaluatorToken::EvaluatorToken() |
2411 | +{ |
2412 | + type = 0; |
2413 | + value.fl = 0; |
2414 | +} |
2415 | + |
2416 | +ExpressionEvaluator::ExpressionEvaluator(const char *string, Unit *unit) : |
2417 | + string(string), |
2418 | + unit(unit) |
2419 | +{ |
2420 | + current_token.type = TOKEN_END; |
2421 | + |
2422 | + // Preload symbol |
2423 | + parseNextToken(); |
2424 | +} |
2425 | |
2426 | /** |
2427 | * Evaluates the given arithmetic expression, along with an optional dimension |
2428 | * analysis, and basic unit conversions. |
2429 | * |
2430 | - * @param string The NULL-terminated string to be evaluated. |
2431 | - * @param unit_resolver_proc Unit resolver callback. |
2432 | - * |
2433 | * All units conversions factors are relative to some implicit |
2434 | - * base-unit (which in GIMP is inches). This is also the unit of the |
2435 | - * returned value. |
2436 | + * base-unit. This is also the unit of the returned value. |
2437 | * |
2438 | - * Returns: A #GimpEevlQuantity with a value given in the base unit along with |
2439 | - * the order of the dimension (i.e. if the base unit is inches, a dimension |
2440 | - * order of two menas in^2). |
2441 | + * Returns: An EvaluatorQuantity with a value given in the base unit along with |
2442 | + * the order of the dimension (e.g. if the base unit is inches, a dimension |
2443 | + * order of two means in^2). |
2444 | * |
2445 | * @return Result of evaluation. |
2446 | * @throws Inkscape::Util::EvaluatorException There was a parse error. |
2447 | **/ |
2448 | -GimpEevlQuantity |
2449 | -gimp_eevl_evaluate (const gchar* string, Unit* unit) |
2450 | +EvaluatorQuantity ExpressionEvaluator::evaluate() |
2451 | { |
2452 | - if (! g_utf8_validate (string, -1, NULL)) { |
2453 | + if (!g_utf8_validate(string, -1, NULL)) { |
2454 | throw EvaluatorException("Invalid UTF8 string", NULL); |
2455 | } |
2456 | - |
2457 | - GimpEevl eva; |
2458 | - gimp_eevl_init (&eva, string, unitresolverproc, unit); |
2459 | - |
2460 | - return gimp_eevl_complete(&eva); |
2461 | -} |
2462 | - |
2463 | -static void |
2464 | -gimp_eevl_init (GimpEevl *eva, |
2465 | - const gchar *string, |
2466 | - GimpEevlUnitResolverProc unit_resolver_proc, |
2467 | - Unit *unit) |
2468 | -{ |
2469 | - eva->string = string; |
2470 | - eva->unit_resolver_proc = unit_resolver_proc; |
2471 | - eva->unit = unit; |
2472 | - |
2473 | - eva->current_token.type = GIMP_EEVL_TOKEN_END; |
2474 | - |
2475 | - /* Preload symbol... */ |
2476 | - gimp_eevl_lex (eva); |
2477 | -} |
2478 | - |
2479 | -static GimpEevlQuantity |
2480 | -gimp_eevl_complete (GimpEevl *eva) |
2481 | -{ |
2482 | - GimpEevlQuantity result = {0, 0}; |
2483 | - GimpEevlQuantity default_unit_factor; |
2484 | - |
2485 | - /* Empty expression evaluates to 0 */ |
2486 | - if (gimp_eevl_accept (eva, GIMP_EEVL_TOKEN_END, NULL)) |
2487 | - return result; |
2488 | - |
2489 | - result = gimp_eevl_expression (eva); |
2490 | - |
2491 | - /* There should be nothing left to parse by now */ |
2492 | - gimp_eevl_expect (eva, GIMP_EEVL_TOKEN_END, 0); |
2493 | - |
2494 | - eva->unit_resolver_proc (NULL, &default_unit_factor, eva->unit); |
2495 | - |
2496 | - /* Entire expression is dimensionless, apply default unit if |
2497 | - * applicable |
2498 | - */ |
2499 | - if (result.dimension == 0 && default_unit_factor.dimension != 0) |
2500 | - { |
2501 | - result.value /= default_unit_factor.value; |
2502 | - result.dimension = default_unit_factor.dimension; |
2503 | - } |
2504 | - return result; |
2505 | -} |
2506 | - |
2507 | -static GimpEevlQuantity |
2508 | -gimp_eevl_expression (GimpEevl *eva) |
2509 | -{ |
2510 | - gboolean subtract; |
2511 | - GimpEevlQuantity evaluated_terms; |
2512 | - |
2513 | - evaluated_terms = gimp_eevl_term (eva); |
2514 | - |
2515 | - /* continue evaluating terms, chained with + or -. */ |
2516 | - for (subtract = FALSE; |
2517 | - gimp_eevl_accept (eva, '+', NULL) || |
2518 | - (subtract = gimp_eevl_accept (eva, '-', NULL)); |
2519 | - subtract = FALSE) |
2520 | - { |
2521 | - GimpEevlQuantity new_term = gimp_eevl_term (eva); |
2522 | - |
2523 | - /* If dimensions missmatch, attempt default unit assignent */ |
2524 | - if (new_term.dimension != evaluated_terms.dimension) |
2525 | - { |
2526 | - GimpEevlQuantity default_unit_factor; |
2527 | - |
2528 | - eva->unit_resolver_proc (NULL, |
2529 | - &default_unit_factor, |
2530 | - eva->unit); |
2531 | - |
2532 | - if (new_term.dimension == 0 && |
2533 | - evaluated_terms.dimension == default_unit_factor.dimension) |
2534 | - { |
2535 | - new_term.value /= default_unit_factor.value; |
2536 | - new_term.dimension = default_unit_factor.dimension; |
2537 | - } |
2538 | - else if (evaluated_terms.dimension == 0 && |
2539 | - new_term.dimension == default_unit_factor.dimension) |
2540 | - { |
2541 | - evaluated_terms.value /= default_unit_factor.value; |
2542 | - evaluated_terms.dimension = default_unit_factor.dimension; |
2543 | - } |
2544 | - else |
2545 | - { |
2546 | - gimp_eevl_error (eva, "Dimension missmatch during addition"); |
2547 | - } |
2548 | - } |
2549 | - |
2550 | - evaluated_terms.value += (subtract ? -new_term.value : new_term.value); |
2551 | - } |
2552 | - |
2553 | - return evaluated_terms; |
2554 | -} |
2555 | - |
2556 | -static GimpEevlQuantity |
2557 | -gimp_eevl_term (GimpEevl *eva) |
2558 | -{ |
2559 | - gboolean division; |
2560 | - GimpEevlQuantity evaluated_signed_factors; |
2561 | - |
2562 | - evaluated_signed_factors = gimp_eevl_signed_factor (eva); |
2563 | - |
2564 | - for (division = FALSE; |
2565 | - gimp_eevl_accept (eva, '*', NULL) || |
2566 | - (division = gimp_eevl_accept (eva, '/', NULL)); |
2567 | - division = FALSE) |
2568 | - { |
2569 | - GimpEevlQuantity new_signed_factor = gimp_eevl_signed_factor (eva); |
2570 | - |
2571 | - if (division) |
2572 | - { |
2573 | - evaluated_signed_factors.value /= new_signed_factor.value; |
2574 | - evaluated_signed_factors.dimension -= new_signed_factor.dimension; |
2575 | - |
2576 | - } |
2577 | - else |
2578 | - { |
2579 | - evaluated_signed_factors.value *= new_signed_factor.value; |
2580 | - evaluated_signed_factors.dimension += new_signed_factor.dimension; |
2581 | - } |
2582 | - } |
2583 | - |
2584 | - return evaluated_signed_factors; |
2585 | -} |
2586 | - |
2587 | -static GimpEevlQuantity |
2588 | -gimp_eevl_signed_factor (GimpEevl *eva) |
2589 | -{ |
2590 | - GimpEevlQuantity result; |
2591 | - gboolean negate = FALSE; |
2592 | - |
2593 | - if (! gimp_eevl_accept (eva, '+', NULL)) |
2594 | - negate = gimp_eevl_accept (eva, '-', NULL); |
2595 | - |
2596 | - result = gimp_eevl_factor (eva); |
2597 | - |
2598 | - if (negate) result.value = -result.value; |
2599 | - |
2600 | - return result; |
2601 | -} |
2602 | - |
2603 | -static GimpEevlQuantity |
2604 | -gimp_eevl_factor (GimpEevl *eva) |
2605 | -{ |
2606 | - GimpEevlQuantity evaluated_factor = { 0, 0 }; |
2607 | - GimpEevlToken consumed_token; |
2608 | - |
2609 | - if (gimp_eevl_accept (eva, |
2610 | - GIMP_EEVL_TOKEN_NUM, |
2611 | - &consumed_token)) |
2612 | - { |
2613 | - evaluated_factor.value = consumed_token.value.fl; |
2614 | - } |
2615 | - else if (gimp_eevl_accept (eva, '(', NULL)) |
2616 | - { |
2617 | - evaluated_factor = gimp_eevl_expression (eva); |
2618 | - gimp_eevl_expect (eva, ')', 0); |
2619 | - } |
2620 | - else |
2621 | - { |
2622 | - gimp_eevl_error (eva, "Expected number or '('"); |
2623 | - } |
2624 | - |
2625 | - if (eva->current_token.type == GIMP_EEVL_TOKEN_IDENTIFIER) |
2626 | - { |
2627 | - gchar *identifier; |
2628 | - GimpEevlQuantity result; |
2629 | - |
2630 | - gimp_eevl_accept (eva, |
2631 | - GIMP_EEVL_TOKEN_ANY, |
2632 | - &consumed_token); |
2633 | - |
2634 | - identifier = g_newa (gchar, consumed_token.value.size + 1); |
2635 | - |
2636 | - strncpy (identifier, consumed_token.value.c, consumed_token.value.size); |
2637 | - identifier[consumed_token.value.size] = '\0'; |
2638 | - |
2639 | - if (eva->unit_resolver_proc (identifier, |
2640 | - &result, |
2641 | - eva->unit)) |
2642 | - { |
2643 | - evaluated_factor.value /= result.value; |
2644 | - evaluated_factor.dimension += result.dimension; |
2645 | - } |
2646 | - else |
2647 | - { |
2648 | - gimp_eevl_error (eva, "Unit was not resolved"); |
2649 | - } |
2650 | - } |
2651 | - |
2652 | - return evaluated_factor; |
2653 | -} |
2654 | - |
2655 | -static gboolean |
2656 | -gimp_eevl_accept (GimpEevl *eva, |
2657 | - GimpEevlTokenType token_type, |
2658 | - GimpEevlToken *consumed_token) |
2659 | -{ |
2660 | - gboolean existed = FALSE; |
2661 | - |
2662 | - if (token_type == eva->current_token.type || |
2663 | - token_type == GIMP_EEVL_TOKEN_ANY) |
2664 | - { |
2665 | - existed = TRUE; |
2666 | - |
2667 | - if (consumed_token) |
2668 | - *consumed_token = eva->current_token; |
2669 | - |
2670 | - /* Parse next token */ |
2671 | - gimp_eevl_lex (eva); |
2672 | - } |
2673 | - |
2674 | - return existed; |
2675 | -} |
2676 | - |
2677 | -static void |
2678 | -gimp_eevl_lex (GimpEevl *eva) |
2679 | -{ |
2680 | - const gchar *s; |
2681 | - |
2682 | - gimp_eevl_move_past_whitespace (eva); |
2683 | - s = eva->string; |
2684 | - eva->start_of_current_token = s; |
2685 | - |
2686 | - if (! s || s[0] == '\0') |
2687 | - { |
2688 | - /* We're all done */ |
2689 | - eva->current_token.type = GIMP_EEVL_TOKEN_END; |
2690 | - } |
2691 | - else if (s[0] == '+' || s[0] == '-') |
2692 | - { |
2693 | - /* Snatch these before the g_strtod() does, othewise they might |
2694 | - * be used in a numeric conversion. |
2695 | - */ |
2696 | - gimp_eevl_lex_accept_count (eva, 1, s[0]); |
2697 | - } |
2698 | - else |
2699 | - |
2700 | - { |
2701 | - /* Attempt to parse a numeric value */ |
2702 | - gchar *endptr = NULL; |
2703 | - gdouble value = g_strtod (s, &endptr); |
2704 | - |
2705 | - if (endptr && endptr != s) |
2706 | - { |
2707 | - /* A numeric could be parsed, use it */ |
2708 | - eva->current_token.value.fl = value; |
2709 | - |
2710 | - gimp_eevl_lex_accept_to (eva, endptr, GIMP_EEVL_TOKEN_NUM); |
2711 | - } |
2712 | - else if (gimp_eevl_unit_identifier_start (s[0])) |
2713 | - { |
2714 | - /* Unit identifier */ |
2715 | - eva->current_token.value.c = s; |
2716 | - eva->current_token.value.size = gimp_eevl_unit_identifier_size (s, 0); |
2717 | - |
2718 | - gimp_eevl_lex_accept_count (eva, |
2719 | - eva->current_token.value.size, |
2720 | - GIMP_EEVL_TOKEN_IDENTIFIER); |
2721 | - } |
2722 | - else |
2723 | - { |
2724 | - /* Everything else is a single character token */ |
2725 | - gimp_eevl_lex_accept_count (eva, 1, s[0]); |
2726 | - } |
2727 | - } |
2728 | -} |
2729 | - |
2730 | -static void |
2731 | -gimp_eevl_lex_accept_count (GimpEevl *eva, |
2732 | - gint count, |
2733 | - GimpEevlTokenType token_type) |
2734 | -{ |
2735 | - eva->current_token.type = token_type; |
2736 | - eva->string += count; |
2737 | -} |
2738 | - |
2739 | -static void |
2740 | -gimp_eevl_lex_accept_to (GimpEevl *eva, |
2741 | - gchar *to, |
2742 | - GimpEevlTokenType token_type) |
2743 | -{ |
2744 | - eva->current_token.type = token_type; |
2745 | - eva->string = to; |
2746 | -} |
2747 | - |
2748 | -static void |
2749 | -gimp_eevl_move_past_whitespace (GimpEevl *eva) |
2750 | -{ |
2751 | - if (! eva->string) |
2752 | - return; |
2753 | - |
2754 | - while (g_ascii_isspace (*eva->string)) |
2755 | - eva->string++; |
2756 | -} |
2757 | - |
2758 | -static gboolean |
2759 | -gimp_eevl_unit_identifier_start (gunichar c) |
2760 | -{ |
2761 | - return (g_unichar_isalpha (c) || |
2762 | - c == (gunichar) '%' || |
2763 | - c == (gunichar) '\''); |
2764 | -} |
2765 | - |
2766 | -static gboolean |
2767 | -gimp_eevl_unit_identifier_continue (gunichar c) |
2768 | -{ |
2769 | - return (gimp_eevl_unit_identifier_start (c) || |
2770 | - g_unichar_isdigit (c)); |
2771 | + |
2772 | + EvaluatorQuantity result = EvaluatorQuantity(); |
2773 | + EvaluatorQuantity default_unit_factor; |
2774 | + |
2775 | + // Empty expression evaluates to 0 |
2776 | + if (acceptToken(TOKEN_END, NULL)) { |
2777 | + return result; |
2778 | + } |
2779 | + |
2780 | + result = evaluateExpression(); |
2781 | + |
2782 | + // There should be nothing left to parse by now |
2783 | + isExpected(TOKEN_END, 0); |
2784 | + |
2785 | + resolveUnit(NULL, &default_unit_factor, unit); |
2786 | + |
2787 | + // Entire expression is dimensionless, apply default unit if applicable |
2788 | + if ( result.dimension == 0 && default_unit_factor.dimension != 0 ) { |
2789 | + result.value /= default_unit_factor.value; |
2790 | + result.dimension = default_unit_factor.dimension; |
2791 | + } |
2792 | + return result; |
2793 | +} |
2794 | + |
2795 | +EvaluatorQuantity ExpressionEvaluator::evaluateExpression() |
2796 | +{ |
2797 | + bool subtract; |
2798 | + EvaluatorQuantity evaluated_terms; |
2799 | + |
2800 | + evaluated_terms = evaluateTerm(); |
2801 | + |
2802 | + // Continue evaluating terms, chained with + or -. |
2803 | + for (subtract = FALSE; |
2804 | + acceptToken('+', NULL) || (subtract = acceptToken('-', NULL)); |
2805 | + subtract = FALSE) |
2806 | + { |
2807 | + EvaluatorQuantity new_term = evaluateTerm(); |
2808 | + |
2809 | + // If dimensions mismatch, attempt default unit assignent |
2810 | + if ( new_term.dimension != evaluated_terms.dimension ) { |
2811 | + EvaluatorQuantity default_unit_factor; |
2812 | + |
2813 | + resolveUnit(NULL, &default_unit_factor, unit); |
2814 | + |
2815 | + if ( new_term.dimension == 0 |
2816 | + && evaluated_terms.dimension == default_unit_factor.dimension ) |
2817 | + { |
2818 | + new_term.value /= default_unit_factor.value; |
2819 | + new_term.dimension = default_unit_factor.dimension; |
2820 | + } else if ( evaluated_terms.dimension == 0 |
2821 | + && new_term.dimension == default_unit_factor.dimension ) |
2822 | + { |
2823 | + evaluated_terms.value /= default_unit_factor.value; |
2824 | + evaluated_terms.dimension = default_unit_factor.dimension; |
2825 | + } else { |
2826 | + throwError("Dimension mismatch during addition"); |
2827 | + } |
2828 | + } |
2829 | + |
2830 | + evaluated_terms.value += (subtract ? -new_term.value : new_term.value); |
2831 | + } |
2832 | + |
2833 | + return evaluated_terms; |
2834 | +} |
2835 | + |
2836 | +EvaluatorQuantity ExpressionEvaluator::evaluateTerm() |
2837 | +{ |
2838 | + bool division; |
2839 | + EvaluatorQuantity evaluated_exp_terms = evaluateExpTerm(); |
2840 | + |
2841 | + for ( division = false; |
2842 | + acceptToken('*', NULL) || (division = acceptToken('/', NULL)); |
2843 | + division = false ) |
2844 | + { |
2845 | + EvaluatorQuantity new_exp_term = evaluateExpTerm(); |
2846 | + |
2847 | + if (division) { |
2848 | + evaluated_exp_terms.value /= new_exp_term.value; |
2849 | + evaluated_exp_terms.dimension -= new_exp_term.dimension; |
2850 | + } else { |
2851 | + evaluated_exp_terms.value *= new_exp_term.value; |
2852 | + evaluated_exp_terms.dimension += new_exp_term.dimension; |
2853 | + } |
2854 | + } |
2855 | + |
2856 | + return evaluated_exp_terms; |
2857 | +} |
2858 | + |
2859 | +EvaluatorQuantity ExpressionEvaluator::evaluateExpTerm() |
2860 | +{ |
2861 | + EvaluatorQuantity evaluated_signed_factors = evaluateSignedFactor(); |
2862 | + |
2863 | + while(acceptToken('^', NULL)) { |
2864 | + EvaluatorQuantity new_signed_factor = evaluateSignedFactor(); |
2865 | + |
2866 | + if (new_signed_factor.dimension == 0) { |
2867 | + evaluated_signed_factors.value = pow(evaluated_signed_factors.value, |
2868 | + new_signed_factor.value); |
2869 | + evaluated_signed_factors.dimension *= new_signed_factor.value; |
2870 | + } else { |
2871 | + throwError("Unit in exponent"); |
2872 | + } |
2873 | + } |
2874 | + |
2875 | + return evaluated_signed_factors; |
2876 | +} |
2877 | + |
2878 | +EvaluatorQuantity ExpressionEvaluator::evaluateSignedFactor() |
2879 | +{ |
2880 | + EvaluatorQuantity result; |
2881 | + bool negate = FALSE; |
2882 | + |
2883 | + if (!acceptToken('+', NULL)) { |
2884 | + negate = acceptToken ('-', NULL); |
2885 | + } |
2886 | + |
2887 | + result = evaluateFactor(); |
2888 | + |
2889 | + if (negate) { |
2890 | + result.value = -result.value; |
2891 | + } |
2892 | + |
2893 | + return result; |
2894 | +} |
2895 | + |
2896 | +EvaluatorQuantity ExpressionEvaluator::evaluateFactor() |
2897 | +{ |
2898 | + EvaluatorQuantity evaluated_factor = EvaluatorQuantity(); |
2899 | + EvaluatorToken consumed_token = EvaluatorToken(); |
2900 | + |
2901 | + if (acceptToken(TOKEN_NUM, &consumed_token)) { |
2902 | + evaluated_factor.value = consumed_token.value.fl; |
2903 | + } else if (acceptToken('(', NULL)) { |
2904 | + evaluated_factor = evaluateExpression(); |
2905 | + isExpected(')', 0); |
2906 | + } else { |
2907 | + throwError("Expected number or '('"); |
2908 | + } |
2909 | + |
2910 | + if ( current_token.type == TOKEN_IDENTIFIER ) { |
2911 | + char *identifier; |
2912 | + EvaluatorQuantity result; |
2913 | + |
2914 | + acceptToken(TOKEN_ANY, &consumed_token); |
2915 | + |
2916 | + identifier = g_newa(char, consumed_token.value.size + 1); |
2917 | + |
2918 | + strncpy(identifier, consumed_token.value.c, consumed_token.value.size); |
2919 | + identifier[consumed_token.value.size] = '\0'; |
2920 | + |
2921 | + if (resolveUnit(identifier, &result, unit)) { |
2922 | + evaluated_factor.value /= result.value; |
2923 | + evaluated_factor.dimension += result.dimension; |
2924 | + } else { |
2925 | + throwError("Unit was not resolved"); |
2926 | + } |
2927 | + } |
2928 | + |
2929 | + return evaluated_factor; |
2930 | +} |
2931 | + |
2932 | +bool ExpressionEvaluator::acceptToken(TokenType token_type, |
2933 | + EvaluatorToken *consumed_token) |
2934 | +{ |
2935 | + bool existed = FALSE; |
2936 | + |
2937 | + if ( token_type == current_token.type || token_type == TOKEN_ANY ) { |
2938 | + existed = TRUE; |
2939 | + |
2940 | + if (consumed_token) { |
2941 | + *consumed_token = current_token; |
2942 | + } |
2943 | + |
2944 | + // Parse next token |
2945 | + parseNextToken(); |
2946 | + } |
2947 | + |
2948 | + return existed; |
2949 | +} |
2950 | + |
2951 | +void ExpressionEvaluator::parseNextToken() |
2952 | +{ |
2953 | + const char *s; |
2954 | + |
2955 | + movePastWhiteSpace(); |
2956 | + s = string; |
2957 | + start_of_current_token = s; |
2958 | + |
2959 | + if ( !s || s[0] == '\0' ) { |
2960 | + // We're all done |
2961 | + current_token.type = TOKEN_END; |
2962 | + } else if ( s[0] == '+' || s[0] == '-' ) { |
2963 | + // Snatch these before the g_strtod() does, othewise they might |
2964 | + // be used in a numeric conversion. |
2965 | + acceptTokenCount(1, s[0]); |
2966 | + } else { |
2967 | + // Attempt to parse a numeric value |
2968 | + char *endptr = NULL; |
2969 | + gdouble value = g_strtod(s, &endptr); |
2970 | + |
2971 | + if ( endptr && endptr != s ) { |
2972 | + // A numeric could be parsed, use it |
2973 | + current_token.value.fl = value; |
2974 | + |
2975 | + current_token.type = TOKEN_NUM; |
2976 | + string = endptr; |
2977 | + } else if (isUnitIdentifierStart(s[0])) { |
2978 | + // Unit identifier |
2979 | + current_token.value.c = s; |
2980 | + current_token.value.size = getIdentifierSize(s, 0); |
2981 | + |
2982 | + acceptTokenCount(current_token.value.size, TOKEN_IDENTIFIER); |
2983 | + } else { |
2984 | + // Everything else is a single character token |
2985 | + acceptTokenCount(1, s[0]); |
2986 | + } |
2987 | + } |
2988 | +} |
2989 | + |
2990 | +void ExpressionEvaluator::acceptTokenCount (int count, TokenType token_type) |
2991 | +{ |
2992 | + current_token.type = token_type; |
2993 | + string += count; |
2994 | +} |
2995 | + |
2996 | +void ExpressionEvaluator::isExpected(TokenType token_type, |
2997 | + EvaluatorToken *value) |
2998 | +{ |
2999 | + if (!acceptToken(token_type, value)) { |
3000 | + throwError("Unexpected token"); |
3001 | + } |
3002 | +} |
3003 | + |
3004 | +void ExpressionEvaluator::movePastWhiteSpace() |
3005 | +{ |
3006 | + if (!string) { |
3007 | + return; |
3008 | + } |
3009 | + |
3010 | + while (g_ascii_isspace(*string)) { |
3011 | + string++; |
3012 | + } |
3013 | +} |
3014 | + |
3015 | +bool ExpressionEvaluator::isUnitIdentifierStart(gunichar c) |
3016 | +{ |
3017 | + return (g_unichar_isalpha (c) |
3018 | + || c == (gunichar) '%' |
3019 | + || c == (gunichar) '\''); |
3020 | } |
3021 | |
3022 | /** |
3023 | - * gimp_eevl_unit_identifier_size: |
3024 | + * getIdentifierSize: |
3025 | * @s: |
3026 | * @start: |
3027 | * |
3028 | * Returns: Size of identifier in bytes (not including NULL |
3029 | * terminator). |
3030 | **/ |
3031 | -static gint |
3032 | -gimp_eevl_unit_identifier_size (const gchar *string, |
3033 | - gint start_offset) |
3034 | +int ExpressionEvaluator::getIdentifierSize(const char *string, int start_offset) |
3035 | { |
3036 | - const gchar *start = g_utf8_offset_to_pointer (string, start_offset); |
3037 | - const gchar *s = start; |
3038 | - gunichar c = g_utf8_get_char (s); |
3039 | - gint length = 0; |
3040 | - |
3041 | - if (gimp_eevl_unit_identifier_start (c)) |
3042 | - { |
3043 | - s = g_utf8_next_char (s); |
3044 | - c = g_utf8_get_char (s); |
3045 | - length++; |
3046 | - |
3047 | - while (gimp_eevl_unit_identifier_continue (c)) |
3048 | - { |
3049 | - s = g_utf8_next_char (s); |
3050 | - c = g_utf8_get_char (s); |
3051 | - length++; |
3052 | + const char *start = g_utf8_offset_to_pointer(string, start_offset); |
3053 | + const char *s = start; |
3054 | + gunichar c = g_utf8_get_char(s); |
3055 | + int length = 0; |
3056 | + |
3057 | + if (isUnitIdentifierStart(c)) { |
3058 | + s = g_utf8_next_char (s); |
3059 | + c = g_utf8_get_char (s); |
3060 | + length++; |
3061 | + |
3062 | + while ( isUnitIdentifierStart (c) || g_unichar_isdigit (c) ) { |
3063 | + s = g_utf8_next_char(s); |
3064 | + c = g_utf8_get_char(s); |
3065 | + length++; |
3066 | } |
3067 | } |
3068 | - |
3069 | - return g_utf8_offset_to_pointer (start, length) - start; |
3070 | -} |
3071 | - |
3072 | -static void |
3073 | -gimp_eevl_expect (GimpEevl *eva, |
3074 | - GimpEevlTokenType token_type, |
3075 | - GimpEevlToken *value) |
3076 | -{ |
3077 | - if (! gimp_eevl_accept (eva, token_type, value)) |
3078 | - gimp_eevl_error (eva, "Unexpected token"); |
3079 | -} |
3080 | - |
3081 | -static void |
3082 | -gimp_eevl_error (GimpEevl *eva, |
3083 | - const char *msg) |
3084 | -{ |
3085 | - throw EvaluatorException(msg, eva->start_of_current_token); |
3086 | + |
3087 | + return g_utf8_offset_to_pointer(start, length) - start; |
3088 | +} |
3089 | + |
3090 | +bool ExpressionEvaluator::resolveUnit (const char* identifier, |
3091 | + EvaluatorQuantity *result, |
3092 | + Unit* unit) |
3093 | +{ |
3094 | + if (!unit) { |
3095 | + result->value = 1; |
3096 | + result->dimension = 1; |
3097 | + return true; |
3098 | + }else if (!identifier) { |
3099 | + result->value = 1; |
3100 | + result->dimension = unit->isAbsolute() ? 1 : 0; |
3101 | + return true; |
3102 | + } else if (unit_table.hasUnit(identifier)) { |
3103 | + Unit identifier_unit = unit_table.getUnit(identifier); |
3104 | + result->value = Quantity::convert(1, *unit, identifier_unit); |
3105 | + result->dimension = identifier_unit.isAbsolute() ? 1 : 0; |
3106 | + return true; |
3107 | + } else { |
3108 | + return false; |
3109 | + } |
3110 | +} |
3111 | + |
3112 | +void ExpressionEvaluator::throwError(const char *msg) |
3113 | +{ |
3114 | + throw EvaluatorException(msg, start_of_current_token); |
3115 | } |
3116 | |
3117 | } // namespace Util |
3118 | |
3119 | === modified file 'src/util/expression-evaluator.h' |
3120 | --- src/util/expression-evaluator.h 2011-10-27 04:55:51 +0000 |
3121 | +++ src/util/expression-evaluator.h 2013-09-20 17:05:49 +0000 |
3122 | @@ -6,6 +6,7 @@ |
3123 | * Copyright (C) 2008-2009 Martin Nordholts <martinn@svn.gnome.org> |
3124 | * Modified for Inkscape by Johan Engelen |
3125 | * Copyright (C) 2011 Johan Engelen |
3126 | + * Copyright (C) 2013 Matthew Petroff |
3127 | * |
3128 | * This library is free software: you can redistribute it and/or |
3129 | * modify it under the terms of the GNU Lesser General Public |
3130 | @@ -22,8 +23,8 @@ |
3131 | * <http://www.gnu.org/licenses/>. |
3132 | */ |
3133 | |
3134 | -#ifndef SEEN_GIMP_EEVL_H |
3135 | -#define SEEN_GIMP_EEVL_H |
3136 | +#ifndef INKSCAPE_UTIL_EXPRESSION_EVALUATOR_H |
3137 | +#define INKSCAPE_UTIL_EXPRESSION_EVALUATOR_H |
3138 | |
3139 | #include "util/units.h" |
3140 | |
3141 | @@ -33,7 +34,7 @@ |
3142 | |
3143 | /** |
3144 | * @file |
3145 | - * Introducing eevl eva, the evaluator. A straightforward recursive |
3146 | + * Expression evaluator: A straightforward recursive |
3147 | * descent parser, no fuss, no new dependencies. The lexer is hand |
3148 | * coded, tedious, not extremely fast but works. It evaluates the |
3149 | * expression as it goes along, and does not create a parse tree or |
3150 | @@ -43,8 +44,8 @@ |
3151 | * |
3152 | * It relies on external unit resolving through a callback and does |
3153 | * elementary dimensionality constraint check (e.g. "2 mm + 3 px * 4 |
3154 | - * in" is an error, as L + L^2 is a missmatch). It uses g_strtod() for numeric |
3155 | - * conversions and it's non-destructive in terms of the paramters, and |
3156 | + * in" is an error, as L + L^2 is a mismatch). It uses g_strtod() for numeric |
3157 | + * conversions and it's non-destructive in terms of the parameters, and |
3158 | * it's reentrant. |
3159 | * |
3160 | * EBNF: |
3161 | @@ -52,7 +53,9 @@ |
3162 | * expression ::= term { ('+' | '-') term }* | |
3163 | * <empty string> ; |
3164 | * |
3165 | - * term ::= signed factor { ( '*' | '/' ) signed factor }* ; |
3166 | + * term ::= exponent { ( '*' | '/' ) exponent }* ; |
3167 | + * |
3168 | + * exponent ::= signed factor { '^' signed factor }* ; |
3169 | * |
3170 | * signed factor ::= ( '+' | '-' )? factor ; |
3171 | * |
3172 | @@ -79,37 +82,104 @@ |
3173 | class Unit; |
3174 | |
3175 | /** |
3176 | -* GimpEevlQuantity: |
3177 | -* @value: In reference units. |
3178 | -* @dimension: in has a dimension of 1, in^2 has a dimension of 2 etc |
3179 | -*/ |
3180 | -typedef struct |
3181 | + * EvaluatorQuantity: |
3182 | + * @param value In reference units. |
3183 | + * @param dimension mm has a dimension of 1, mm^2 has a dimension of 2, etc. |
3184 | + */ |
3185 | +class EvaluatorQuantity |
3186 | { |
3187 | +public: |
3188 | + EvaluatorQuantity(double value = 0, unsigned int dimension = 0); |
3189 | + |
3190 | double value; |
3191 | - gint dimension; |
3192 | -} GimpEevlQuantity; |
3193 | - |
3194 | -typedef bool (* GimpEevlUnitResolverProc) (const gchar *identifier, |
3195 | - GimpEevlQuantity *result, |
3196 | - Unit* unit); |
3197 | - |
3198 | -GimpEevlQuantity gimp_eevl_evaluate (const gchar* string, Unit* unit = NULL); |
3199 | + unsigned int dimension; |
3200 | +}; |
3201 | + |
3202 | +/** |
3203 | + * TokenType |
3204 | + */ |
3205 | +enum { |
3206 | + TOKEN_NUM = 30000, |
3207 | + TOKEN_IDENTIFIER = 30001, |
3208 | + TOKEN_ANY = 40000, |
3209 | + TOKEN_END = 50000 |
3210 | +}; |
3211 | +typedef int TokenType; |
3212 | + |
3213 | +/** |
3214 | + * EvaluatorToken |
3215 | + */ |
3216 | +class EvaluatorToken |
3217 | +{ |
3218 | +public: |
3219 | + EvaluatorToken(); |
3220 | + |
3221 | + TokenType type; |
3222 | + |
3223 | + union { |
3224 | + double fl; |
3225 | + struct { |
3226 | + const char *c; |
3227 | + int size; |
3228 | + }; |
3229 | + } value; |
3230 | +}; |
3231 | + |
3232 | +/** |
3233 | + * ExpressionEvaluator |
3234 | + * @param string NULL terminated input string to evaluate |
3235 | + * @param unit Unit output should be in |
3236 | + */ |
3237 | +class ExpressionEvaluator |
3238 | +{ |
3239 | +public: |
3240 | + ExpressionEvaluator(const char *string, Unit *unit = NULL); |
3241 | + |
3242 | + EvaluatorQuantity evaluate(); |
3243 | + |
3244 | +private: |
3245 | + const char *string; |
3246 | + Unit *unit; |
3247 | + |
3248 | + EvaluatorToken current_token; |
3249 | + const char *start_of_current_token; |
3250 | + |
3251 | + EvaluatorQuantity evaluateExpression(); |
3252 | + EvaluatorQuantity evaluateTerm(); |
3253 | + EvaluatorQuantity evaluateExpTerm(); |
3254 | + EvaluatorQuantity evaluateSignedFactor(); |
3255 | + EvaluatorQuantity evaluateFactor(); |
3256 | + |
3257 | + bool acceptToken(TokenType token_type, EvaluatorToken *consumed_token); |
3258 | + void parseNextToken(); |
3259 | + void acceptTokenCount(int count, TokenType token_type); |
3260 | + void isExpected(TokenType token_type, EvaluatorToken *value); |
3261 | + |
3262 | + void movePastWhiteSpace(); |
3263 | + |
3264 | + static bool isUnitIdentifierStart(gunichar c); |
3265 | + static int getIdentifierSize(const char *s, int start); |
3266 | + |
3267 | + static bool resolveUnit(const char *identifier, EvaluatorQuantity *result, Unit *unit); |
3268 | + |
3269 | + void throwError(const char *msg); |
3270 | +}; |
3271 | |
3272 | /** |
3273 | * Special exception class for the expression evaluator. |
3274 | */ |
3275 | class EvaluatorException : public std::exception { |
3276 | public: |
3277 | - EvaluatorException(const char * message, const char *at_position) { |
3278 | + EvaluatorException(const char *message, const char *at_position) { |
3279 | std::ostringstream os; |
3280 | - const char* token = at_position ? at_position : "<End of input>"; |
3281 | + const char *token = at_position ? at_position : "<End of input>"; |
3282 | os << "Expression evaluator error: " << message << " at '" << token << "'"; |
3283 | msgstr = os.str(); |
3284 | } |
3285 | |
3286 | virtual ~EvaluatorException() throw() {} // necessary to destroy the string object!!! |
3287 | |
3288 | - virtual const char* what() const throw () { |
3289 | + virtual const char *what() const throw () { |
3290 | return msgstr.c_str(); |
3291 | } |
3292 | protected: |
3293 | @@ -119,4 +189,4 @@ |
3294 | } |
3295 | } |
3296 | |
3297 | -#endif // SEEN_GIMP_EEVL_H |
3298 | +#endif // INKSCAPE_UTIL_EXPRESSION_EVALUATOR_H |
3299 | |
3300 | === modified file 'src/util/units.cpp' |
3301 | --- src/util/units.cpp 2013-09-01 17:34:44 +0000 |
3302 | +++ src/util/units.cpp 2013-09-20 17:05:49 +0000 |
3303 | @@ -114,6 +114,7 @@ |
3304 | abbr(abbr), |
3305 | description(description) |
3306 | { |
3307 | + g_return_if_fail(factor <= 0); |
3308 | } |
3309 | |
3310 | void Unit::clear() |
3311 | @@ -166,25 +167,25 @@ |
3312 | int Unit::svgUnit() const |
3313 | { |
3314 | if (!abbr.compare("px")) |
3315 | - return 1; |
3316 | + return SVGLength::PX; |
3317 | if (!abbr.compare("pt")) |
3318 | - return 2; |
3319 | + return SVGLength::PT; |
3320 | if (!abbr.compare("pc")) |
3321 | - return 3; |
3322 | + return SVGLength::PC; |
3323 | if (!abbr.compare("mm")) |
3324 | - return 4; |
3325 | + return SVGLength::MM; |
3326 | if (!abbr.compare("cm")) |
3327 | - return 5; |
3328 | + return SVGLength::CM; |
3329 | if (!abbr.compare("in")) |
3330 | - return 6; |
3331 | + return SVGLength::INCH; |
3332 | if (!abbr.compare("ft")) |
3333 | - return 7; |
3334 | + return SVGLength::FOOT; |
3335 | if (!abbr.compare("em")) |
3336 | - return 8; |
3337 | + return SVGLength::EM; |
3338 | if (!abbr.compare("ex")) |
3339 | - return 9; |
3340 | + return SVGLength::EX; |
3341 | if (!abbr.compare("%")) |
3342 | - return 10; |
3343 | + return SVGLength::PERCENT; |
3344 | return 0; |
3345 | } |
3346 | |
3347 | @@ -220,6 +221,36 @@ |
3348 | return Unit(); |
3349 | } |
3350 | } |
3351 | +Unit UnitTable::getUnit(SVGLength::Unit const u) const |
3352 | +{ |
3353 | + Glib::ustring u_str; |
3354 | + switch(u) { |
3355 | + case SVGLength::PX: |
3356 | + u_str = "px"; break; |
3357 | + case SVGLength::PT: |
3358 | + u_str = "pt"; break; |
3359 | + case SVGLength::PC: |
3360 | + u_str = "pc"; break; |
3361 | + case SVGLength::MM: |
3362 | + u_str = "mm"; break; |
3363 | + case SVGLength::CM: |
3364 | + u_str = "cm"; break; |
3365 | + case SVGLength::INCH: |
3366 | + u_str = "in"; break; |
3367 | + case SVGLength::FOOT: |
3368 | + u_str = "ft"; break; |
3369 | + case SVGLength::EM: |
3370 | + u_str = "em"; break; |
3371 | + case SVGLength::EX: |
3372 | + u_str = "ex"; break; |
3373 | + case SVGLength::PERCENT: |
3374 | + u_str = "%"; break; |
3375 | + default: |
3376 | + u_str = ""; |
3377 | + } |
3378 | + |
3379 | + return getUnit(u_str); |
3380 | +} |
3381 | |
3382 | Quantity UnitTable::getQuantity(Glib::ustring const& q) const |
3383 | { |
3384 | @@ -421,6 +452,27 @@ |
3385 | return convert(from_dist, unit_table.getUnit(from), unit_table.getUnit(to)); |
3386 | } |
3387 | |
3388 | +bool operator< (const Quantity &ql, const Quantity &qr) |
3389 | +{ |
3390 | + if (ql.unit->type != qr.unit->type) { |
3391 | + g_warning("Incompatible units"); |
3392 | + return false; |
3393 | + } |
3394 | + return ql.quantity < qr.value(*ql.unit); |
3395 | +} |
3396 | +bool operator> (const Quantity &ql, const Quantity &qr) |
3397 | +{ |
3398 | + if (ql.unit->type != qr.unit->type) { |
3399 | + g_warning("Incompatible units"); |
3400 | + return false; |
3401 | + } |
3402 | + return ql.quantity > qr.value(*ql.unit); |
3403 | +} |
3404 | +bool operator!= (const Quantity &q1, const Quantity &q2) |
3405 | +{ |
3406 | + return (*q1.unit != *q2.unit) || (q1.quantity != q2.quantity); |
3407 | +} |
3408 | + |
3409 | } // namespace Util |
3410 | } // namespace Inkscape |
3411 | |
3412 | |
3413 | === modified file 'src/util/units.h' |
3414 | --- src/util/units.h 2013-08-04 22:01:18 +0000 |
3415 | +++ src/util/units.h 2013-09-20 17:05:49 +0000 |
3416 | @@ -1,5 +1,6 @@ |
3417 | /* |
3418 | * Inkscape Units |
3419 | + * These classes are used for defining different unit systems. |
3420 | * |
3421 | * Authors: |
3422 | * Matthew Petroff <matthew@mpetroff.net> |
3423 | @@ -9,25 +10,12 @@ |
3424 | * Released under GNU GPL, read the file 'COPYING' for more information |
3425 | */ |
3426 | |
3427 | -/* |
3428 | -This is a rough draft of a global 'units' thingee, to allow dialogs and |
3429 | -the ruler to share info about unit systems... Dunno if this is the |
3430 | -right kind of object though, so we may have to redo this or shift things |
3431 | -around later when it becomes clearer what we need. |
3432 | - |
3433 | -This object is used for defining different unit systems. |
3434 | - |
3435 | -This is intended to eventually replace inkscape/helper/units.*. |
3436 | - |
3437 | -Need to review the Units support that's in Gtkmm already... |
3438 | - |
3439 | -*/ |
3440 | - |
3441 | #ifndef INKSCAPE_UTIL_UNITS_H |
3442 | #define INKSCAPE_UTIL_UNITS_H |
3443 | |
3444 | #include <map> |
3445 | #include <glibmm/ustring.h> |
3446 | +#include "svg/svg-length.h" |
3447 | |
3448 | namespace Inkscape { |
3449 | namespace Util { |
3450 | @@ -112,6 +100,11 @@ |
3451 | static double convert(const double from_dist, const Glib::ustring from, const Unit &to); |
3452 | static double convert(const double from_dist, const Unit &from, const Glib::ustring to); |
3453 | static double convert(const double from_dist, const Glib::ustring from, const Glib::ustring to); |
3454 | + |
3455 | + /** Comparison operators. */ |
3456 | + friend bool operator< (const Quantity &ql, const Quantity &qr); |
3457 | + friend bool operator> (const Quantity &ql, const Quantity &qr); |
3458 | + friend bool operator!= (const Quantity &q1, const Quantity &q2); |
3459 | }; |
3460 | |
3461 | class UnitTable { |
3462 | @@ -132,6 +125,9 @@ |
3463 | /** Retrieve a given unit based on its string identifier */ |
3464 | Unit getUnit(Glib::ustring const &name) const; |
3465 | |
3466 | + /** Retrieve a given unit based on its SVGLength unit */ |
3467 | + Unit getUnit(SVGLength::Unit const u) const; |
3468 | + |
3469 | /** Retrieve a quantity based on its string identifier */ |
3470 | Quantity getQuantity(Glib::ustring const &q) const; |
3471 | |
3472 | |
3473 | === modified file 'src/widgets/calligraphy-toolbar.cpp' |
3474 | --- src/widgets/calligraphy-toolbar.cpp 2013-07-19 18:19:03 +0000 |
3475 | +++ src/widgets/calligraphy-toolbar.cpp 2013-09-20 17:05:49 +0000 |
3476 | @@ -450,7 +450,7 @@ |
3477 | GTK_WIDGET(desktop->canvas), holder, TRUE, "altx-calligraphy", |
3478 | 1, 100, 1.0, 10.0, |
3479 | labels, values, G_N_ELEMENTS(labels), |
3480 | - sp_ddc_width_value_changed, 1, 0 ); |
3481 | + sp_ddc_width_value_changed, NULL /*unit tracker*/, 1, 0 ); |
3482 | ege_adjustment_action_set_appearance( eact, TOOLBAR_SLIDER_HINT ); |
3483 | gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); |
3484 | gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); |
3485 | @@ -467,7 +467,7 @@ |
3486 | GTK_WIDGET(desktop->canvas), holder, FALSE, NULL, |
3487 | -100, 100, 1, 10.0, |
3488 | labels, values, G_N_ELEMENTS(labels), |
3489 | - sp_ddc_velthin_value_changed, 1, 0); |
3490 | + sp_ddc_velthin_value_changed, NULL /*unit tracker*/, 1, 0); |
3491 | gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); |
3492 | gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); |
3493 | } |
3494 | @@ -483,7 +483,7 @@ |
3495 | GTK_WIDGET(desktop->canvas), holder, TRUE, "calligraphy-angle", |
3496 | -90.0, 90.0, 1.0, 10.0, |
3497 | labels, values, G_N_ELEMENTS(labels), |
3498 | - sp_ddc_angle_value_changed, 1, 0 ); |
3499 | + sp_ddc_angle_value_changed, NULL /*unit tracker*/, 1, 0 ); |
3500 | gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); |
3501 | g_object_set_data( holder, "angle_action", eact ); |
3502 | gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); |
3503 | @@ -501,7 +501,7 @@ |
3504 | GTK_WIDGET(desktop->canvas), holder, FALSE, NULL, |
3505 | 0.0, 100, 1.0, 10.0, |
3506 | labels, values, G_N_ELEMENTS(labels), |
3507 | - sp_ddc_flatness_value_changed, 1, 0); |
3508 | + sp_ddc_flatness_value_changed, NULL /*unit tracker*/, 1, 0); |
3509 | gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); |
3510 | gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); |
3511 | } |
3512 | @@ -518,7 +518,7 @@ |
3513 | GTK_WIDGET(desktop->canvas), holder, FALSE, NULL, |
3514 | 0.0, 5.0, 0.01, 0.1, |
3515 | labels, values, G_N_ELEMENTS(labels), |
3516 | - sp_ddc_cap_rounding_value_changed, 0.01, 2 ); |
3517 | + sp_ddc_cap_rounding_value_changed, NULL /*unit tracker*/, 0.01, 2 ); |
3518 | gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); |
3519 | gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); |
3520 | } |
3521 | @@ -534,7 +534,7 @@ |
3522 | GTK_WIDGET(desktop->canvas), holder, FALSE, NULL, |
3523 | 0.0, 100, 1, 10.0, |
3524 | labels, values, G_N_ELEMENTS(labels), |
3525 | - sp_ddc_tremor_value_changed, 1, 0); |
3526 | + sp_ddc_tremor_value_changed, NULL /*unit tracker*/, 1, 0); |
3527 | |
3528 | ege_adjustment_action_set_appearance( eact, TOOLBAR_SLIDER_HINT ); |
3529 | gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); |
3530 | @@ -552,7 +552,7 @@ |
3531 | GTK_WIDGET(desktop->canvas), holder, FALSE, NULL, |
3532 | 0.0, 100, 1, 10.0, |
3533 | labels, values, G_N_ELEMENTS(labels), |
3534 | - sp_ddc_wiggle_value_changed, 1, 0); |
3535 | + sp_ddc_wiggle_value_changed, NULL /*unit tracker*/, 1, 0); |
3536 | ege_adjustment_action_set_appearance( eact, TOOLBAR_SLIDER_HINT ); |
3537 | gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); |
3538 | gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); |
3539 | @@ -569,7 +569,7 @@ |
3540 | GTK_WIDGET(desktop->canvas), holder, FALSE, NULL, |
3541 | 0.0, 100, 1, 10.0, |
3542 | labels, values, G_N_ELEMENTS(labels), |
3543 | - sp_ddc_mass_value_changed, 1, 0); |
3544 | + sp_ddc_mass_value_changed, NULL /*unit tracker*/, 1, 0); |
3545 | ege_adjustment_action_set_appearance( eact, TOOLBAR_SLIDER_HINT ); |
3546 | gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); |
3547 | gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); |
3548 | |
3549 | === modified file 'src/widgets/connector-toolbar.cpp' |
3550 | --- src/widgets/connector-toolbar.cpp 2013-07-19 18:19:03 +0000 |
3551 | +++ src/widgets/connector-toolbar.cpp 2013-09-20 17:05:49 +0000 |
3552 | @@ -364,7 +364,7 @@ |
3553 | GTK_WIDGET(desktop->canvas), holder, TRUE, "inkscape:connector-curvature", |
3554 | 0, 100, 1.0, 10.0, |
3555 | 0, 0, 0, |
3556 | - connector_curvature_changed, 1, 0 ); |
3557 | + connector_curvature_changed, NULL /*unit tracker*/, 1, 0 ); |
3558 | gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); |
3559 | |
3560 | // Spacing spinbox |
3561 | @@ -375,7 +375,7 @@ |
3562 | GTK_WIDGET(desktop->canvas), holder, TRUE, "inkscape:connector-spacing", |
3563 | 0, 100, 1.0, 10.0, |
3564 | 0, 0, 0, |
3565 | - connector_spacing_changed, 1, 0 ); |
3566 | + connector_spacing_changed, NULL /*unit tracker*/, 1, 0 ); |
3567 | gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); |
3568 | |
3569 | // Graph (connector network) layout |
3570 | @@ -397,7 +397,7 @@ |
3571 | GTK_WIDGET(desktop->canvas), holder, TRUE, "inkscape:connector-length", |
3572 | 10, 1000, 10.0, 100.0, |
3573 | 0, 0, 0, |
3574 | - connector_length_changed, 1, 0 ); |
3575 | + connector_length_changed, NULL /*unit tracker*/, 1, 0 ); |
3576 | gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); |
3577 | |
3578 | |
3579 | |
3580 | === modified file 'src/widgets/desktop-widget.cpp' |
3581 | --- src/widgets/desktop-widget.cpp 2013-08-30 21:35:42 +0000 |
3582 | +++ src/widgets/desktop-widget.cpp 2013-09-20 17:05:49 +0000 |
3583 | @@ -2135,8 +2135,8 @@ |
3584 | |
3585 | /* The desktop region we always show unconditionally */ |
3586 | SPDocument *doc = dtw->desktop->doc(); |
3587 | - Geom::Rect darea ( Geom::Point(-doc->getWidth(), -doc->getHeight()), |
3588 | - Geom::Point(2 * doc->getWidth(), 2 * doc->getHeight()) ); |
3589 | + Geom::Rect darea ( Geom::Point(-doc->getWidth().value("px"), -doc->getHeight().value("px")), |
3590 | + Geom::Point(2 * doc->getWidth().value("px"), 2 * doc->getHeight().value("px")) ); |
3591 | |
3592 | Geom::OptRect deskarea; |
3593 | if (Inkscape::Preferences::get()->getInt("/tools/bounding_box") == 0) { |
3594 | |
3595 | === modified file 'src/widgets/eraser-toolbar.cpp' |
3596 | --- src/widgets/eraser-toolbar.cpp 2013-07-30 01:54:37 +0000 |
3597 | +++ src/widgets/eraser-toolbar.cpp 2013-09-20 17:05:49 +0000 |
3598 | @@ -148,7 +148,7 @@ |
3599 | GTK_WIDGET(desktop->canvas), holder, TRUE, "altx-eraser", |
3600 | 1, 100, 1.0, 10.0, |
3601 | labels, values, G_N_ELEMENTS(labels), |
3602 | - sp_erc_width_value_changed, 1, 0); |
3603 | + sp_erc_width_value_changed, NULL /*unit tracker*/, 1, 0); |
3604 | ege_adjustment_action_set_appearance( eact, TOOLBAR_SLIDER_HINT ); |
3605 | gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); |
3606 | gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); |
3607 | |
3608 | === modified file 'src/widgets/gradient-toolbar.cpp' |
3609 | --- src/widgets/gradient-toolbar.cpp 2013-08-30 21:35:42 +0000 |
3610 | +++ src/widgets/gradient-toolbar.cpp 2013-09-20 17:05:49 +0000 |
3611 | @@ -1175,8 +1175,9 @@ |
3612 | GTK_WIDGET(desktop->canvas), holder, FALSE, NULL, |
3613 | 0.0, 1.0, 0.01, 0.1, |
3614 | 0, 0, 0, |
3615 | - gr_stop_offset_adjustment_changed |
3616 | - , 0.01, 2, 1.0); |
3617 | + gr_stop_offset_adjustment_changed, |
3618 | + NULL /*unit tracker*/, |
3619 | + 0.01, 2, 1.0); |
3620 | |
3621 | gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); |
3622 | g_object_set_data( holder, "offset_action", eact ); |
3623 | |
3624 | === modified file 'src/widgets/icon.cpp' |
3625 | --- src/widgets/icon.cpp 2013-06-12 15:14:48 +0000 |
3626 | +++ src/widgets/icon.cpp 2013-09-20 17:05:49 +0000 |
3627 | @@ -42,6 +42,7 @@ |
3628 | #include "display/drawing.h" |
3629 | #include "io/sys.h" |
3630 | #include "sp-root.h" |
3631 | +#include "util/units.h" |
3632 | |
3633 | #include "icon.h" |
3634 | |
3635 | @@ -1137,7 +1138,7 @@ |
3636 | if ( object->parent == NULL ) |
3637 | { |
3638 | dbox = Geom::Rect(Geom::Point(0, 0), |
3639 | - Geom::Point(doc->getWidth(), doc->getHeight())); |
3640 | + Geom::Point(doc->getWidth().value("px"), doc->getHeight().value("px"))); |
3641 | } |
3642 | |
3643 | /* This is in document coordinates, i.e. pixels */ |
3644 | |
3645 | === modified file 'src/widgets/mesh-toolbar.cpp' |
3646 | --- src/widgets/mesh-toolbar.cpp 2013-07-19 18:19:03 +0000 |
3647 | +++ src/widgets/mesh-toolbar.cpp 2013-09-20 17:05:49 +0000 |
3648 | @@ -265,7 +265,7 @@ |
3649 | GTK_WIDGET(desktop->canvas), holder, FALSE, NULL, |
3650 | 1, 20, 1, 1, |
3651 | labels, values, G_N_ELEMENTS(labels), |
3652 | - ms_row_changed, |
3653 | + ms_row_changed, NULL /*unit tracker*/, |
3654 | 1.0, 0 ); |
3655 | gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); |
3656 | gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); |
3657 | @@ -281,7 +281,7 @@ |
3658 | GTK_WIDGET(desktop->canvas), holder, FALSE, NULL, |
3659 | 1, 20, 1, 1, |
3660 | labels, values, G_N_ELEMENTS(labels), |
3661 | - ms_col_changed, |
3662 | + ms_col_changed, NULL /*unit tracker*/, |
3663 | 1.0, 0 ); |
3664 | gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); |
3665 | gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); |
3666 | |
3667 | === modified file 'src/widgets/node-toolbar.cpp' |
3668 | --- src/widgets/node-toolbar.cpp 2013-08-04 22:01:18 +0000 |
3669 | +++ src/widgets/node-toolbar.cpp 2013-09-20 17:05:49 +0000 |
3670 | @@ -595,7 +595,7 @@ |
3671 | GTK_WIDGET(desktop->canvas), holder, TRUE, "altx-nodes", |
3672 | -1e6, 1e6, SPIN_STEP, SPIN_PAGE_STEP, |
3673 | labels, values, G_N_ELEMENTS(labels), |
3674 | - sp_node_path_x_value_changed ); |
3675 | + sp_node_path_x_value_changed, tracker ); |
3676 | tracker->addAdjustment( ege_adjustment_action_get_adjustment(eact) ); |
3677 | g_object_set_data( holder, "nodes_x_action", eact ); |
3678 | gtk_action_set_sensitive( GTK_ACTION(eact), FALSE ); |
3679 | @@ -613,7 +613,7 @@ |
3680 | GTK_WIDGET(desktop->canvas), holder, FALSE, NULL, |
3681 | -1e6, 1e6, SPIN_STEP, SPIN_PAGE_STEP, |
3682 | labels, values, G_N_ELEMENTS(labels), |
3683 | - sp_node_path_y_value_changed ); |
3684 | + sp_node_path_y_value_changed, tracker ); |
3685 | tracker->addAdjustment( ege_adjustment_action_get_adjustment(eact) ); |
3686 | g_object_set_data( holder, "nodes_y_action", eact ); |
3687 | gtk_action_set_sensitive( GTK_ACTION(eact), FALSE ); |
3688 | |
3689 | === modified file 'src/widgets/paintbucket-toolbar.cpp' |
3690 | --- src/widgets/paintbucket-toolbar.cpp 2013-08-30 21:35:42 +0000 |
3691 | +++ src/widgets/paintbucket-toolbar.cpp 2013-09-20 17:05:49 +0000 |
3692 | @@ -169,7 +169,7 @@ |
3693 | "/tools/paintbucket/threshold", 5, GTK_WIDGET(desktop->canvas), holder, TRUE, |
3694 | "inkscape:paintbucket-threshold", 0, 100.0, 1.0, 10.0, |
3695 | 0, 0, 0, |
3696 | - paintbucket_threshold_changed, 1, 0 ); |
3697 | + paintbucket_threshold_changed, NULL /*unit tracker*/, 1, 0 ); |
3698 | |
3699 | ege_adjustment_action_set_appearance( eact, TOOLBAR_SLIDER_HINT ); |
3700 | gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); |
3701 | @@ -197,7 +197,7 @@ |
3702 | "/tools/paintbucket/offset", 0, GTK_WIDGET(desktop->canvas), holder, TRUE, |
3703 | "inkscape:paintbucket-offset", -1e4, 1e4, 0.1, 0.5, |
3704 | 0, 0, 0, |
3705 | - paintbucket_offset_changed, 1, 2); |
3706 | + paintbucket_offset_changed, tracker, 1, 2); |
3707 | tracker->addAdjustment( ege_adjustment_action_get_adjustment(eact) ); |
3708 | |
3709 | gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); |
3710 | |
3711 | === modified file 'src/widgets/pencil-toolbar.cpp' |
3712 | --- src/widgets/pencil-toolbar.cpp 2013-07-19 18:19:03 +0000 |
3713 | +++ src/widgets/pencil-toolbar.cpp 2013-09-20 17:05:49 +0000 |
3714 | @@ -307,6 +307,7 @@ |
3715 | 1, 100.0, 0.5, 1.0, |
3716 | labels, values, G_N_ELEMENTS(labels), |
3717 | sp_pencil_tb_tolerance_value_changed, |
3718 | + NULL /*unit tracker*/, |
3719 | 1, 2); |
3720 | ege_adjustment_action_set_appearance( eact, TOOLBAR_SLIDER_HINT ); |
3721 | gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); |
3722 | |
3723 | === modified file 'src/widgets/rect-toolbar.cpp' |
3724 | --- src/widgets/rect-toolbar.cpp 2013-08-30 21:35:42 +0000 |
3725 | +++ src/widgets/rect-toolbar.cpp 2013-09-20 17:05:49 +0000 |
3726 | @@ -114,7 +114,7 @@ |
3727 | for (GSList const *items = selection->itemList(); items != NULL; items = items->next) { |
3728 | if (SP_IS_RECT(items->data)) { |
3729 | if (gtk_adjustment_get_value(adj) != 0) { |
3730 | - (SP_RECT(items->data)->*setter)(Quantity::convert(gtk_adjustment_get_value(adj), unit, "px")); |
3731 | + (SP_RECT(items->data)->*setter)(Quantity::convert(gtk_adjustment_get_value(adj), unit, *sp_desktop_namedview(desktop)->doc_units)); |
3732 | } else { |
3733 | SP_OBJECT(items->data)->getRepr()->setAttribute(value_name, NULL); |
3734 | } |
3735 | @@ -186,6 +186,7 @@ |
3736 | |
3737 | UnitTracker* tracker = reinterpret_cast<UnitTracker*>( g_object_get_data( tbl, "tracker" ) ); |
3738 | Unit const unit = tracker->getActiveUnit(); |
3739 | + Unit const doc_unit = *sp_desktop_namedview(SP_ACTIVE_DESKTOP)->doc_units; |
3740 | |
3741 | gpointer item = g_object_get_data( tbl, "item" ); |
3742 | if (item && SP_IS_RECT(item)) { |
3743 | @@ -193,28 +194,28 @@ |
3744 | GtkAdjustment *adj = GTK_ADJUSTMENT( g_object_get_data( tbl, "rx" ) ); |
3745 | |
3746 | gdouble rx = SP_RECT(item)->getVisibleRx(); |
3747 | - gtk_adjustment_set_value(adj, Quantity::convert(rx, "px", unit)); |
3748 | + gtk_adjustment_set_value(adj, Quantity::convert(rx, doc_unit, unit)); |
3749 | } |
3750 | |
3751 | { |
3752 | GtkAdjustment *adj = GTK_ADJUSTMENT( g_object_get_data( tbl, "ry" ) ); |
3753 | |
3754 | gdouble ry = SP_RECT(item)->getVisibleRy(); |
3755 | - gtk_adjustment_set_value(adj, Quantity::convert(ry, "px", unit)); |
3756 | + gtk_adjustment_set_value(adj, Quantity::convert(ry, doc_unit, unit)); |
3757 | } |
3758 | |
3759 | { |
3760 | GtkAdjustment *adj = GTK_ADJUSTMENT( g_object_get_data( tbl, "width" ) ); |
3761 | |
3762 | gdouble width = SP_RECT(item)->getVisibleWidth(); |
3763 | - gtk_adjustment_set_value(adj, Quantity::convert(width, "px", unit)); |
3764 | + gtk_adjustment_set_value(adj, Quantity::convert(width, doc_unit, unit)); |
3765 | } |
3766 | |
3767 | { |
3768 | GtkAdjustment *adj = GTK_ADJUSTMENT( g_object_get_data( tbl, "height" ) ); |
3769 | |
3770 | gdouble height = SP_RECT(item)->getVisibleHeight(); |
3771 | - gtk_adjustment_set_value(adj, Quantity::convert(height, "px", unit)); |
3772 | + gtk_adjustment_set_value(adj, Quantity::convert(height, doc_unit, unit)); |
3773 | } |
3774 | } |
3775 | |
3776 | @@ -322,7 +323,7 @@ |
3777 | GTK_WIDGET(desktop->canvas), holder, TRUE, "altx-rect", |
3778 | 0, 1e6, SPIN_STEP, SPIN_PAGE_STEP, |
3779 | labels, values, G_N_ELEMENTS(labels), |
3780 | - sp_rtb_width_value_changed ); |
3781 | + sp_rtb_width_value_changed, tracker); |
3782 | tracker->addAdjustment( ege_adjustment_action_get_adjustment(eact) ); |
3783 | g_object_set_data( holder, "width_action", eact ); |
3784 | gtk_action_set_sensitive( GTK_ACTION(eact), FALSE ); |
3785 | @@ -339,7 +340,7 @@ |
3786 | GTK_WIDGET(desktop->canvas), holder, FALSE, NULL, |
3787 | 0, 1e6, SPIN_STEP, SPIN_PAGE_STEP, |
3788 | labels, values, G_N_ELEMENTS(labels), |
3789 | - sp_rtb_height_value_changed ); |
3790 | + sp_rtb_height_value_changed, tracker); |
3791 | tracker->addAdjustment( ege_adjustment_action_get_adjustment(eact) ); |
3792 | g_object_set_data( holder, "height_action", eact ); |
3793 | gtk_action_set_sensitive( GTK_ACTION(eact), FALSE ); |
3794 | @@ -356,7 +357,7 @@ |
3795 | GTK_WIDGET(desktop->canvas), holder, FALSE, NULL, |
3796 | 0, 1e6, SPIN_STEP, SPIN_PAGE_STEP, |
3797 | labels, values, G_N_ELEMENTS(labels), |
3798 | - sp_rtb_rx_value_changed); |
3799 | + sp_rtb_rx_value_changed, tracker); |
3800 | tracker->addAdjustment( ege_adjustment_action_get_adjustment(eact) ); |
3801 | gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); |
3802 | } |
3803 | @@ -371,7 +372,7 @@ |
3804 | GTK_WIDGET(desktop->canvas), holder, FALSE, NULL, |
3805 | 0, 1e6, SPIN_STEP, SPIN_PAGE_STEP, |
3806 | labels, values, G_N_ELEMENTS(labels), |
3807 | - sp_rtb_ry_value_changed); |
3808 | + sp_rtb_ry_value_changed, tracker); |
3809 | tracker->addAdjustment( ege_adjustment_action_get_adjustment(eact) ); |
3810 | gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); |
3811 | } |
3812 | |
3813 | === modified file 'src/widgets/select-toolbar.cpp' |
3814 | --- src/widgets/select-toolbar.cpp 2013-08-04 22:01:18 +0000 |
3815 | +++ src/widgets/select-toolbar.cpp 2013-09-20 17:05:49 +0000 |
3816 | @@ -273,7 +273,7 @@ |
3817 | g_object_set_data(G_OBJECT(spw), "update", GINT_TO_POINTER(FALSE)); |
3818 | } |
3819 | |
3820 | -static GtkWidget* createCustomSlider( GtkAdjustment *adjustment, gdouble climbRate, guint digits ) |
3821 | +static GtkWidget* createCustomSlider( GtkAdjustment *adjustment, gdouble climbRate, guint digits, Inkscape::UI::Widget::UnitTracker *unit_tracker ) |
3822 | { |
3823 | #if WITH_GTKMM_3_0 |
3824 | Glib::RefPtr<Gtk::Adjustment> adj = Glib::wrap(adjustment, true); |
3825 | @@ -281,6 +281,7 @@ |
3826 | #else |
3827 | Inkscape::UI::Widget::SpinButton *inkSpinner = new Inkscape::UI::Widget::SpinButton(*Glib::wrap(adjustment, true), climbRate, digits); |
3828 | #endif |
3829 | + inkSpinner->addUnitTracker(unit_tracker); |
3830 | inkSpinner = Gtk::manage( inkSpinner ); |
3831 | GtkWidget *widget = GTK_WIDGET( inkSpinner->gobj() ); |
3832 | return widget; |
3833 | @@ -313,7 +314,7 @@ |
3834 | g_object_set_data( G_OBJECT(spw), data, adj ); |
3835 | } |
3836 | |
3837 | - EgeAdjustmentAction* act = ege_adjustment_action_new( adj, name, Q_(label), tooltip, 0, SPIN_STEP, 3 ); |
3838 | + EgeAdjustmentAction* act = ege_adjustment_action_new( adj, name, Q_(label), tooltip, 0, SPIN_STEP, 3, tracker ); |
3839 | if ( shortLabel ) { |
3840 | g_object_set( act, "short_label", Q_(shortLabel), NULL ); |
3841 | } |
3842 | |
3843 | === modified file 'src/widgets/spiral-toolbar.cpp' |
3844 | --- src/widgets/spiral-toolbar.cpp 2013-07-19 18:19:03 +0000 |
3845 | +++ src/widgets/spiral-toolbar.cpp 2013-09-20 17:05:49 +0000 |
3846 | @@ -262,7 +262,7 @@ |
3847 | GTK_WIDGET(desktop->canvas), holder, TRUE, "altx-spiral", |
3848 | 0.01, 1024.0, 0.1, 1.0, |
3849 | labels, values, G_N_ELEMENTS(labels), |
3850 | - sp_spl_tb_revolution_value_changed, 1, 2); |
3851 | + sp_spl_tb_revolution_value_changed, NULL /*unit tracker*/, 1, 2); |
3852 | gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); |
3853 | } |
3854 | |
3855 | |
3856 | === modified file 'src/widgets/spray-toolbar.cpp' |
3857 | --- src/widgets/spray-toolbar.cpp 2013-07-19 18:19:03 +0000 |
3858 | +++ src/widgets/spray-toolbar.cpp 2013-09-20 17:05:49 +0000 |
3859 | @@ -130,7 +130,7 @@ |
3860 | GTK_WIDGET(desktop->canvas), holder, TRUE, "altx-spray", |
3861 | 1, 100, 1.0, 10.0, |
3862 | labels, values, G_N_ELEMENTS(labels), |
3863 | - sp_spray_width_value_changed, 1, 0 ); |
3864 | + sp_spray_width_value_changed, NULL /*unit tracker*/, 1, 0 ); |
3865 | ege_adjustment_action_set_appearance( eact, TOOLBAR_SLIDER_HINT ); |
3866 | gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); |
3867 | gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); |
3868 | @@ -146,7 +146,7 @@ |
3869 | GTK_WIDGET(desktop->canvas), holder, TRUE, "spray-mean", |
3870 | 0, 100, 1.0, 10.0, |
3871 | labels, values, G_N_ELEMENTS(labels), |
3872 | - sp_spray_mean_value_changed, 1, 0 ); |
3873 | + sp_spray_mean_value_changed, NULL /*unit tracker*/, 1, 0 ); |
3874 | ege_adjustment_action_set_appearance( eact, TOOLBAR_SLIDER_HINT ); |
3875 | gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); |
3876 | gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); |
3877 | @@ -162,7 +162,7 @@ |
3878 | GTK_WIDGET(desktop->canvas), holder, TRUE, "spray-standard_deviation", |
3879 | 1, 100, 1.0, 10.0, |
3880 | labels, values, G_N_ELEMENTS(labels), |
3881 | - sp_spray_standard_deviation_value_changed, 1, 0 ); |
3882 | + sp_spray_standard_deviation_value_changed, NULL /*unit tracker*/, 1, 0 ); |
3883 | ege_adjustment_action_set_appearance( eact, TOOLBAR_SLIDER_HINT ); |
3884 | gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); |
3885 | gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); |
3886 | @@ -223,7 +223,7 @@ |
3887 | GTK_WIDGET(desktop->canvas), holder, TRUE, "spray-population", |
3888 | 1, 100, 1.0, 10.0, |
3889 | labels, values, G_N_ELEMENTS(labels), |
3890 | - sp_spray_population_value_changed, 1, 0 ); |
3891 | + sp_spray_population_value_changed, NULL /*unit tracker*/, 1, 0 ); |
3892 | ege_adjustment_action_set_appearance( eact, TOOLBAR_SLIDER_HINT ); |
3893 | gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); |
3894 | gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); |
3895 | @@ -254,7 +254,7 @@ |
3896 | GTK_WIDGET(desktop->canvas), holder, TRUE, "spray-rotation", |
3897 | 0, 100, 1.0, 10.0, |
3898 | labels, values, G_N_ELEMENTS(labels), |
3899 | - sp_spray_rotation_value_changed, 1, 0 ); |
3900 | + sp_spray_rotation_value_changed, NULL /*unit tracker*/, 1, 0 ); |
3901 | ege_adjustment_action_set_appearance( eact, TOOLBAR_SLIDER_HINT ); |
3902 | gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); |
3903 | gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); |
3904 | @@ -272,7 +272,7 @@ |
3905 | GTK_WIDGET(desktop->canvas), holder, TRUE, "spray-scale", |
3906 | 0, 100, 1.0, 10.0, |
3907 | labels, values, G_N_ELEMENTS(labels), |
3908 | - sp_spray_scale_value_changed, 1, 0 ); |
3909 | + sp_spray_scale_value_changed, NULL /*unit tracker*/, 1, 0 ); |
3910 | ege_adjustment_action_set_appearance( eact, TOOLBAR_SLIDER_HINT ); |
3911 | gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); |
3912 | gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); |
3913 | |
3914 | === modified file 'src/widgets/star-toolbar.cpp' |
3915 | --- src/widgets/star-toolbar.cpp 2013-07-19 18:19:03 +0000 |
3916 | +++ src/widgets/star-toolbar.cpp 2013-09-20 17:05:49 +0000 |
3917 | @@ -504,7 +504,7 @@ |
3918 | GTK_WIDGET(desktop->canvas), holder, FALSE, NULL, |
3919 | 3, 1024, 1, 5, |
3920 | labels, values, G_N_ELEMENTS(labels), |
3921 | - sp_stb_magnitude_value_changed, |
3922 | + sp_stb_magnitude_value_changed, NULL /*unit tracker*/, |
3923 | 1.0, 0 ); |
3924 | gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); |
3925 | gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); |
3926 | @@ -559,7 +559,7 @@ |
3927 | GTK_WIDGET(desktop->canvas), holder, FALSE, NULL, |
3928 | -10.0, 10.0, 0.001, 0.01, |
3929 | labels, values, G_N_ELEMENTS(labels), |
3930 | - sp_stb_randomized_value_changed, 0.1, 3 ); |
3931 | + sp_stb_randomized_value_changed, NULL /*unit tracker*/, 0.1, 3 ); |
3932 | gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); |
3933 | gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); |
3934 | } |
3935 | |
3936 | === modified file 'src/widgets/text-toolbar.cpp' |
3937 | --- src/widgets/text-toolbar.cpp 2013-07-30 02:51:28 +0000 |
3938 | +++ src/widgets/text-toolbar.cpp 2013-09-20 17:05:49 +0000 |
3939 | @@ -1459,6 +1459,7 @@ |
3940 | 0.0, 10.0, 0.01, 0.10, /* lower, upper, step (arrow up/down), page up/down */ |
3941 | labels, values, G_N_ELEMENTS(labels), /* drop down menu */ |
3942 | sp_text_lineheight_value_changed, /* callback */ |
3943 | + NULL, /* unit tracker */ |
3944 | 0.1, /* step (used?) */ |
3945 | 2, /* digits to show */ |
3946 | 1.0 /* factor (multiplies default) */ |
3947 | @@ -1489,6 +1490,7 @@ |
3948 | -100.0, 100.0, 0.01, 0.10, /* lower, upper, step (arrow up/down), page up/down */ |
3949 | labels, values, G_N_ELEMENTS(labels), /* drop down menu */ |
3950 | sp_text_wordspacing_value_changed, /* callback */ |
3951 | + NULL, /* unit tracker */ |
3952 | 0.1, /* step (used?) */ |
3953 | 2, /* digits to show */ |
3954 | 1.0 /* factor (multiplies default) */ |
3955 | @@ -1519,6 +1521,7 @@ |
3956 | -100.0, 100.0, 0.01, 0.10, /* lower, upper, step (arrow up/down), page up/down */ |
3957 | labels, values, G_N_ELEMENTS(labels), /* drop down menu */ |
3958 | sp_text_letterspacing_value_changed, /* callback */ |
3959 | + NULL, /* unit tracker */ |
3960 | 0.1, /* step (used?) */ |
3961 | 2, /* digits to show */ |
3962 | 1.0 /* factor (multiplies default) */ |
3963 | @@ -1549,6 +1552,7 @@ |
3964 | -100.0, 100.0, 0.01, 0.1, /* lower, upper, step (arrow up/down), page up/down */ |
3965 | labels, values, G_N_ELEMENTS(labels), /* drop down menu */ |
3966 | sp_text_dx_value_changed, /* callback */ |
3967 | + NULL, /* unit tracker */ |
3968 | 0.1, /* step (used?) */ |
3969 | 2, /* digits to show */ |
3970 | 1.0 /* factor (multiplies default) */ |
3971 | @@ -1579,6 +1583,7 @@ |
3972 | -100.0, 100.0, 0.01, 0.1, /* lower, upper, step (arrow up/down), page up/down */ |
3973 | labels, values, G_N_ELEMENTS(labels), /* drop down menu */ |
3974 | sp_text_dy_value_changed, /* callback */ |
3975 | + NULL, /* unit tracker */ |
3976 | 0.1, /* step (used?) */ |
3977 | 2, /* digits to show */ |
3978 | 1.0 /* factor (multiplies default) */ |
3979 | @@ -1609,6 +1614,7 @@ |
3980 | -180.0, 180.0, 0.1, 1.0, /* lower, upper, step (arrow up/down), page up/down */ |
3981 | labels, values, G_N_ELEMENTS(labels), /* drop down menu */ |
3982 | sp_text_rotation_value_changed, /* callback */ |
3983 | + NULL, /* unit tracker */ |
3984 | 0.1, /* step (used?) */ |
3985 | 2, /* digits to show */ |
3986 | 1.0 /* factor (multiplies default) */ |
3987 | |
3988 | === modified file 'src/widgets/toolbox.cpp' |
3989 | --- src/widgets/toolbox.cpp 2013-08-30 21:35:42 +0000 |
3990 | +++ src/widgets/toolbox.cpp 2013-09-20 17:05:49 +0000 |
3991 | @@ -1012,7 +1012,7 @@ |
3992 | return toolboxNewCommon( tb, BAR_SNAP, GTK_POS_LEFT ); |
3993 | } |
3994 | |
3995 | -static GtkWidget* createCustomSlider( GtkAdjustment *adjustment, gdouble climbRate, guint digits ) |
3996 | +static GtkWidget* createCustomSlider( GtkAdjustment *adjustment, gdouble climbRate, guint digits, Inkscape::UI::Widget::UnitTracker *unit_tracker) |
3997 | { |
3998 | #if WITH_GTKMM_3_0 |
3999 | Glib::RefPtr<Gtk::Adjustment> adj = Glib::wrap(adjustment, true); |
4000 | @@ -1020,6 +1020,7 @@ |
4001 | #else |
4002 | Inkscape::UI::Widget::SpinButton *inkSpinner = new Inkscape::UI::Widget::SpinButton(*Glib::wrap(adjustment, true), climbRate, digits); |
4003 | #endif |
4004 | + inkSpinner->addUnitTracker(unit_tracker); |
4005 | inkSpinner = Gtk::manage( inkSpinner ); |
4006 | GtkWidget *widget = GTK_WIDGET( inkSpinner->gobj() ); |
4007 | return widget; |
4008 | @@ -1034,6 +1035,7 @@ |
4009 | gdouble lower, gdouble upper, gdouble step, gdouble page, |
4010 | gchar const** descrLabels, gdouble const* descrValues, guint descrCount, |
4011 | void (*callback)(GtkAdjustment *, GObject *), |
4012 | + Inkscape::UI::Widget::UnitTracker *unit_tracker, |
4013 | gdouble climb/* = 0.1*/, guint digits/* = 3*/, double factor/* = 1.0*/ ) |
4014 | { |
4015 | static bool init = false; |
4016 | @@ -1048,7 +1050,7 @@ |
4017 | |
4018 | g_signal_connect( G_OBJECT(adj), "value-changed", G_CALLBACK(callback), dataKludge ); |
4019 | |
4020 | - EgeAdjustmentAction* act = ege_adjustment_action_new( adj, name, label, tooltip, 0, climb, digits ); |
4021 | + EgeAdjustmentAction* act = ege_adjustment_action_new( adj, name, label, tooltip, 0, climb, digits, unit_tracker ); |
4022 | if ( shortLabel ) { |
4023 | g_object_set( act, "short_label", shortLabel, NULL ); |
4024 | } |
4025 | |
4026 | === modified file 'src/widgets/toolbox.h' |
4027 | --- src/widgets/toolbox.h 2013-08-30 21:35:42 +0000 |
4028 | +++ src/widgets/toolbox.h 2013-09-20 17:05:49 +0000 |
4029 | @@ -28,6 +28,10 @@ |
4030 | namespace Inkscape { |
4031 | namespace UI { |
4032 | |
4033 | +namespace Widget { |
4034 | + class UnitTracker; |
4035 | +} |
4036 | + |
4037 | /** |
4038 | * Main toolbox source. |
4039 | */ |
4040 | @@ -123,6 +127,7 @@ |
4041 | gdouble lower, gdouble upper, gdouble step, gdouble page, |
4042 | gchar const** descrLabels, gdouble const* descrValues, guint descrCount, |
4043 | void (*callback)(GtkAdjustment *, GObject *), |
4044 | + Inkscape::UI::Widget::UnitTracker *unit_tracker = NULL, |
4045 | gdouble climb = 0.1, guint digits = 3, double factor = 1.0 ); |
4046 | |
4047 | #endif /* !SEEN_TOOLBOX_H */ |
4048 | |
4049 | === modified file 'src/widgets/tweak-toolbar.cpp' |
4050 | --- src/widgets/tweak-toolbar.cpp 2013-07-19 18:19:03 +0000 |
4051 | +++ src/widgets/tweak-toolbar.cpp 2013-09-20 17:05:49 +0000 |
4052 | @@ -144,7 +144,7 @@ |
4053 | GTK_WIDGET(desktop->canvas), holder, TRUE, "altx-tweak", |
4054 | 1, 100, 1.0, 10.0, |
4055 | labels, values, G_N_ELEMENTS(labels), |
4056 | - sp_tweak_width_value_changed, 0.01, 0, 100 ); |
4057 | + sp_tweak_width_value_changed, NULL /*unit tracker*/, 0.01, 0, 100 ); |
4058 | ege_adjustment_action_set_appearance( eact, TOOLBAR_SLIDER_HINT ); |
4059 | gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); |
4060 | gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); |
4061 | @@ -161,7 +161,7 @@ |
4062 | GTK_WIDGET(desktop->canvas), holder, TRUE, "tweak-force", |
4063 | 1, 100, 1.0, 10.0, |
4064 | labels, values, G_N_ELEMENTS(labels), |
4065 | - sp_tweak_force_value_changed, 0.01, 0, 100 ); |
4066 | + sp_tweak_force_value_changed, NULL /*unit tracker*/, 0.01, 0, 100 ); |
4067 | ege_adjustment_action_set_appearance( eact, TOOLBAR_SLIDER_HINT ); |
4068 | gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); |
4069 | gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); |
4070 | @@ -370,7 +370,7 @@ |
4071 | GTK_WIDGET(desktop->canvas), holder, TRUE, "tweak-fidelity", |
4072 | 1, 100, 1.0, 10.0, |
4073 | labels, values, G_N_ELEMENTS(labels), |
4074 | - sp_tweak_fidelity_value_changed, 0.01, 0, 100 ); |
4075 | + sp_tweak_fidelity_value_changed, NULL /*unit tracker*/, 0.01, 0, 100 ); |
4076 | gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); |
4077 | gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); |
4078 | if (mode == TWEAK_MODE_COLORPAINT || mode == TWEAK_MODE_COLORJITTER) { |
This code looks good. I'm giving this a thumbs up from a code perspective.