Hi Daniel,

On 03/21/2014 08:41 PM, dmg wrote:
> Sorry I wasn't specific enough. Yes, pen strokes. The reason is that
> with a pressure sensitive stylus, handwritten text  is nicer and more
> readable.
>
> but sometimes I would like to change the thickness of the text after I
> have written it without rescaling it.
>
> Maybe what we need is an option that defaults to set width. If not
> set, rescales width.
>
> I guess the problem is that strokes do not record the maximum width
> text was written with them. The only feasible way is
> to scan the text, find the maximum width, and rescale accordingly:
> newWidth = oldWidth * currentWidth/ maxWidth. That would
> work for me.

Actually strokes DO record the nominal width of the brush (which isn't
quite the maximal width, assuming your stylus uses its full nominal
pressure range -- the maximal width that a variable-width stroke can
reach is slightly more than the width of the corresponding fixed-width
stroke). Cf. width_minimum_multiplier and width_maximum_multiplier
constants in the config file, and the code for get_pressure_multiplier()
in xo-misc.c).

The nominal width is in item->brush.thickness, and if
item->brush.variable_width is TRUE then item->widths contains the widths
of the various segments.

Currently, rethicken_selection() in xo-selection.c just changes
item->brush.width, and sets item->brush.variable_width to FALSE.
item->widths remains unchanged (isn't rescaled, but becomes ignored
since variable_width becomes FALSE; the undo/redo code uses this to be
lazy and also ignore completely item->widths, it simply swaps all the
brush data which will restore variable_width to TRUE... it just works
even though it's counterintuitive!).

What you'll want to do instead is, at the very end of
rethicken_selection(), remove

         item->brush.variable_width = FALSE;

and instead do something like (adding a local variable int i)

         for (i=0; i<item->path->num_points-1; i++)
           item->widths[i] *= item->brush.thickness / brush->thickness;

However you'll also need to change the undo/redo code, in xo-callbacks.c:

in the block

   else if (undo->type == ITEM_REPAINTSEL) { ... }

where it currently says

         // remark: a variable-width item might have lost its variable-width

add

   if (it->brush.variable_width) {
     for (i=0;i<it->path->num_points-1;i++)
       it->widths[i] *= it->brush.thickness / tmp_brush.thickness;
   }

(at this point in the code the brushes have been swapped already so
tmp_brush contains the brush used after the operation being undone,
while it->brush is the brush info before the operation).

Exactly the same in the redo code (insert exactly the same code in the
same place in the ITEM_REPAINTSEL case block).

Not promising that I got it right -- I didn't test -- but it's close
enough that you should be able to figure out how to fix it if I got it
wrong. Doing it with an option is slightly more annoying but you get the
idea.

Note: if you make the option have a menu entry, then there's a subtlety:
in the undo/redo code, to decide which behavior to have, you'd test not
whether the option is active right now, but whether it was active when
the initial operation was performed, by comparing the variable_width
flag in it->brush and tmp_brush: if one is true and the other false then
the repaint operation killed the variable width feature.  Actually
there's a smarter way to do this: always rescale the widths[] arrays
both in rethicken_selection() and in undo/redo code as if the behavior
you want were enabled, and simply make the line
"item->brush.variable_width = FALSE;" in rethicken_selection()
conditional on the option (then it doesn't matter if the widths array
gets updated as in the new behavior, since the variable_width flag being
set to false causes it to be ignored.

Umm, by the way we might be leaking some memory with the widths arrays
of resized strokes when we destroy the journal -- since I'm not sure if
we destroy the widths array when the stroke is no longer marked as
variable-width; in fact I think we forget to destroy it in
delete_layer() in all cases, at least I don't see where it gets
destroyed ever, probably an omission on my part.

What I don't know is if there's ever a risk that a stroke might have a
nominal brush width of 0 (the only significant way I can see this
happening is by rescaling the stroke to something so fine as to be below
0.01 point, then saving to file which rounds things to 2 decimal
places). Given that the "very thin" pen is normally at 0.42 point, you'd
need to resize a selection box containing "very thin" strokes and make
its size at least 80 times smaller than the original one (e.g. by
squishing the selection box to a single point), then save and reload,
for the journal to contain strokes of nominal width zero. However, in
the rather unlikely event that someone ever does this, and then tries to
change the thickness, they'd crash the new code with a division by zero.

Best,
Denis

-- 
Denis Auroux                             aur...@math.berkeley.edu
University of California, Berkeley       Tel: 510-642-4367
Department of Mathematics                Fax: 510-642-8204
817 Evans Hall # 3840
Berkeley, CA 94720-3840


------------------------------------------------------------------------------
Learn Graph Databases - Download FREE O'Reilly Book
"Graph Databases" is the definitive new guide to graph databases and their
applications. Written by three acclaimed leaders in the field,
this first edition is now available. Download your free book today!
http://p.sf.net/sfu/13534_NeoTech
_______________________________________________
Xournal-devel mailing list
Xournal-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/xournal-devel

Reply via email to