simmetric

Spaced text (variable letter and line spacing)

Recommended Posts

Very useful - Many thanks for sharing!B)

 

A few small points:
1. I think the forum prefers .dlls to be 'zipped'.
2. There is already a SubMenuName "Text Formations" - it would be tidier to have this one there too.
3. Configurable anti-aliasing - I can't see a U.I. control for that? although there is an Int32Property for it in PropertyCollection on github?

 

Thanks for sharing the code and welcome to the forum too.

  • Upvote 1

Share this post


Link to post
Share on other sites

A plugin I'm sure I could have used quite a number of times. Like Red ochre, I encourage you to move it to the already-existing "Text Formations" submenu, to prevent a proliferation of similar submenus.

Share this post


Link to post
Share on other sites
9 hours ago, Red ochre said:

1. I think the forum prefers .dlls to be 'zipped'.

 

Optimally, but a naked DLL works.

 

9 hours ago, Red ochre said:

2. There is already a SubMenuName "Text Formations" - it would be tidier to have this one there too.

 

Yes please!

 

Thanks for making the source available too. I appreciate it.

Share this post


Link to post
Share on other sites

Is there a reason the zipped version is preferred? I always thought it was because the forum wouldn't accept raw DLLs, but apparently that's not so. I'd just as soon save a step when posting plugins and skip the zipping (not that it's a big deal).

Share this post


Link to post
Share on other sites

 Some browsers have a fit if you try to download a DLL file. 

Share this post


Link to post
Share on other sites

Then I'll continue to zip them (as simmetric probably should, also).

Share this post


Link to post
Share on other sites

Hi everyone,

 

Thanks for the positive feedback! I've replaced the attachment with a ZIP-file.

 

As for the submenu: text formations seemed to refer to plugins that put text in a certain shape, which is not the goal of my plugin. I tried to find out what submenu the Text+ plugin resides in, but the download link in the topic was dead.

At any rate I agree with not wanting to needlessly introduce a new submenu so the new version resides in Text Formations.

 

19 hours ago, Red ochre said:

A few small points:

...
3. Configurable anti-aliasing - I can't see a U.I. control for that? although there is an Int32Property for it in PropertyCollection on github?

 

This is called AntiAliasingLevel. The slider below LetterSpacing.

Share this post


Link to post
Share on other sites

Hi simmetric

The original (unzipped) version didn't have an Anti-Alias level slider. The new zipped version does.

YibcFT4.png
 

Sorry but please could you recompile to show under "Text Formations". This version appears under "Text formations" - the SubMenuNames are case sensitive.

Apologies for nagging!;)

Share this post


Link to post
Share on other sites
2 hours ago, Red ochre said:

Hi simmetric

The original (unzipped) version didn't have an Anti-Alias level slider. The new zipped version does.

YibcFT4.png
 

Sorry but please could you recompile to show under "Text Formations". This version appears under "Text formations" - the SubMenuNames are case sensitive.

Apologies for nagging!;)

 

Thanks for noticing, I adjusted it and updated the DLL in the opening post.

Strange that the AntiAliasLevel didn't show up for you at first. It's a build from the exact same code. Oh well.

Share this post


Link to post
Share on other sites

Thank you @simmetric!  This will come in handy I'm sure.  

 

spacedtext_01.png

 

Can the LetterSpacing slider go in increments of .01 when using the up/down arrow buttons, instead of 1.00?

Other than that, great job!!   :)

                       

Edited by lynxster4
re-hosted image
  • Upvote 1

Share this post


Link to post
Share on other sites

Thanks for the positive feedback!

 

On 3/8/2017 at 6:41 PM, lynxster4 said:

Can the LetterSpacing slider go in increments of .01 when using the up/down arrow buttons, instead of 1.00?

Other than that, great job!!   :)

                       

 

That's actually what I wanted to do, but I couldn't figure out how. There's no step setting for a DoubleProperty. I've been looking at overriding OnCreateConfigUI but that is a lot more complicated it seems.

 

Is there a tutorial or guide for making advanced config screens?

Share this post


Link to post
Share on other sites
7 hours ago, simmetric said:

That's actually what I wanted to do, but I couldn't figure out how. There's no step setting for a DoubleProperty. I've been looking at overriding OnCreateConfigUI but that is a lot more complicated it seems.

 

Is there a tutorial or guide for making advanced config screens?

 

Simmetric, the step sizes can be set at the time the controls are configured:

            configUI.SetPropertyControlValue(name, ControlInfoPropertyNames.SliderSmallChange, mySliderSmallChange);
            configUI.SetPropertyControlValue(name, ControlInfoPropertyNames.SliderLargeChange, mySliderLargeChange);
            configUI.SetPropertyControlValue(name, ControlInfoPropertyNames.UpDownIncrement, myUpDownIncrement);
            configUI.SetPropertyControlValue(name, ControlInfoPropertyNames.DecimalPlaces, myDecimalPlaces);

 

Share this post


Link to post
Share on other sites

This Plugin will be very useful.  Thank you :D.

Share this post


Link to post
Share on other sites

Simmetric, I looked at the code, and now I see the problem. You don't override OnCreateConfigUI at all. I didn't know that could even be done, since I assumed it was the only way to assign the control labels. Apparently IndirectUI uses the property's name if no label is assigned. If I wrote the config code it would look like this:

protected override ControlInfo OnCreateConfigUI(PropertyCollection props)
{
    ControlInfo configUI = CreateDefaultConfigUI(props);

    configUI.SetPropertyControlValue("Text", ControlInfoPropertyNames.DisplayName, "Text");

    configUI.SetPropertyControlValue("FontSize", ControlInfoPropertyNames.DisplayName, "Font Size");

    configUI.SetPropertyControlValue("LetterSpacing", ControlInfoPropertyNames.DisplayName, "Letter Spacing");
    configUI.SetPropertyControlValue("LetterSpacing", ControlInfoPropertyNames.SliderLargeChange, 0.25);
    configUI.SetPropertyControlValue("LetterSpacing", ControlInfoPropertyNames.SliderSmallChange, 0.05);
    configUI.SetPropertyControlValue("LetterSpacing", ControlInfoPropertyNames.UpDownIncrement, 0.01);
    configUI.SetPropertyControlValue("LetterSpacing", ControlInfoPropertyNames.DecimalPlaces, 2);

    configUI.SetPropertyControlValue("AntiAliasLevel", ControlInfoPropertyNames.DisplayName, "Antialias Level");

    configUI.SetPropertyControlValue("FontFamily", ControlInfoPropertyNames.DisplayName, "Font Family");
    PropertyControlInfo FamilyControl = configUI.FindControlForPropertyName("FontFamily");
    FontFamily[] FontFamilies = new InstalledFontCollection().Families;
    foreach (FontFamily ff in FontFamilies)
    {
        FontFamilyControl.SetValueDisplayName(ff, ff.Name);
    }

    configUI.SetPropertyControlValue("Bold", ControlInfoPropertyNames.DisplayName, string.Empty);
    configUI.SetPropertyControlValue("Bold", ControlInfoPropertyNames.Description, "Bold");

    configUI.SetPropertyControlValue("Italic", ControlInfoPropertyNames.DisplayName, string.Empty);
    configUI.SetPropertyControlValue("Italic", ControlInfoPropertyNames.Description, "Italic");

    configUI.SetPropertyControlValue("Underline", ControlInfoPropertyNames.DisplayName, string.Empty);
    configUI.SetPropertyControlValue("Underline", ControlInfoPropertyNames.Description, "Underline");

    configUI.SetPropertyControlValue("Strikeout", ControlInfoPropertyNames.DisplayName, string.Empty);
    configUI.SetPropertyControlValue("Strikeout", ControlInfoPropertyNames.Description, "Strikeout");

    return configUI;
}

Notes:

1) I haven't tested it, so I there could be typos or other errors.

2) Most of the code was adapted from the code generated by CodeLab. I think that's how many of us learned what to do.

3) I don't understand how the font code I use relates to your version. My version is based on the CodeLab-generated code; beyond that, it's magic to me. (I've never written a plugin that uses a font selector, so I haven't given it much thought.)

4) Apparently the DisplayName code is often unnecessary if the property name is a string. (The property name can be any object. CodeLab uses an enum.) That would mean that the controls like IntSliders don't actually require any code in OnCreateConfigUI.

5) The checkbox configuration sets the DisplayName to an empty string and sets the Description to the label. This results in the control having the label on the same line as the checkbox rather than above it.

 

 

  • Upvote 1

Share this post


Link to post
Share on other sites

Thanks for this tool @simmetric!

 

I like the overlapping of text. I wonder if an outline and shadow option could be added for a cool effect like this :spaced-text-grafiti-51cd017.png

 

  • Upvote 1

Share this post


Link to post
Share on other sites
On 3/11/2017 at 6:27 AM, MJW said:

Simmetric, I looked at the code, and now I see the problem. You don't override OnCreateConfigUI at all. I didn't know that could even be done, since I assumed it was the only way to assign the control labels. Apparently IndirectUI uses the property's name if no label is assigned. If I wrote the config code it would look like this:

 

Thanks very much! The code checked in to Github wasn't overriding OnCreateConfigUI because I couldn't figure out what to do there. The base PropertyBasedEffect class calls CreateDefaultConfigUI by itself.

I'm working this into the plugin and will release a new version hopefully today. It will also have some new features.

 

On 3/11/2017 at 8:15 AM, Eli said:

Thanks for this tool @simmetric!

 

I like the overlapping of text. I wonder if an outline and shadow option could be added for a cool effect like this :spaced-text-grafiti-51cd017.png

 

 

Thanks for the positive feedback!

Unfortunately such shadow and glow effects are outside my goal with the plugin.

Share this post


Link to post
Share on other sites

Alright, I've put version 2.0 up in the first post.

 

Fixes

As per request of @lynxster4, the steps of Letter spacing and Line spacing are now .01, allowing finer control.

 

New features

Automatic line wrapping

Line spacing

Text alignment to left, center or right

 

Work in progress

Justified text: this currently doesn't produce acceptable results. Hopefully I will be able to release this soon.

 

SpacedText-Linespacing2.png

  • Upvote 2

Share this post


Link to post
Share on other sites

@simmetric...thank you for the update.  However, every time I use the arrows to increase spacing between the letters (after I've enlarged the font size), PDN crashes.

Also, if I change the font size after I've spaced the letters, PDN crashes.

It's not usable right now....hopefully there is a fix.

 

Application version: paint.net 4.0.13 (Final 4.13.6191.1824)
Time of crash: 3/13/17 2:40:57 PM
Application uptime: 00:01:12.4871460
Application state: Running 
Working set: 139,816 KiB
Handles and threads: 1454 handles, 29 threads, 164 gdi, 44 user
Install directory: C:\Program Files\paint.net
Current directory: C:\Program Files\Paint.NET
OS Version: 6.1.7601.65536 Service Pack 1 Workstation x86
.NET version: CLR 4.0.30319.42000 x86, FX 4.6
Processor: "Pentium(R) Dual-Core  CPU      E5400  @ 2.70GHz" @ ~2693MHz (2C/2T, DEP, SSE, SSE2, SSE3, SSSE3, XSAVE)
Physical memory: 3037 MB
Video card: Intel(R) G41 Express Chipset (v:8086, d:2E32, r:3)
Hardware acceleration: False (default: False)
UI animations: True
UI DPI: 120.00 dpi (1.25x scale)
UI theme: Aero/Aero + DWM (Aero.msstyles)
Updates: True, 3/6/17
Locale: pdnr.c: en-US, hklm: en-US, hkcu: en-US, cc: en-US, cuic: en-US
Flags: 

Exception details:
System.NullReferenceException: Object reference not set to an instance of an object.
   at System.Windows.Forms.ToolStripProgressBar.get_Value()
   at PaintDotNet.Controls.PdnStatusBar.SetProgressStatusBar(Nullable`1 percent) in D:\src\pdn\src\PaintDotNet\Controls\PdnStatusBar.cs:line 181
   at PaintDotNet.Tools.AsyncSelectionToolBase`2.OnActivated() in D:\src\pdn\src\PaintDotNet\Tools\AsyncSelectionToolBase`2.cs:line 77
   at PaintDotNet.Tools.MagicWand.MagicWandTool.OnActivated() in D:\src\pdn\src\PaintDotNet\Tools\MagicWand\MagicWandTool.cs:line 96
   at PaintDotNet.Tools.TransactedTool`2.OnActivate() in D:\src\pdn\src\PaintDotNet\Tools\TransactedTool`2.cs:line 353
   at PaintDotNet.Tools.Tool.Activate() in D:\src\pdn\src\PaintDotNet\Tools\Tool.cs:line 709
   at PaintDotNet.Controls.DocumentWorkspace.SetTool(Tool copyMe) in D:\src\pdn\src\PaintDotNet\Controls\DocumentWorkspace.cs:line 1560
   at PaintDotNet.Controls.DocumentWorkspace.SetToolFromType(Type toolType) in D:\src\pdn\src\PaintDotNet\Controls\DocumentWorkspace.cs:line 1493
   at PaintDotNet.Controls.DocumentWorkspace.PopNullTool() in D:\src\pdn\src\PaintDotNet\Controls\DocumentWorkspace.cs:line 1517
   at PaintDotNet.PushNullToolMode.Dispose() in D:\src\pdn\src\PaintDotNet\PushNullToolMode.cs:line 32
   at PaintDotNet.Menus.EffectMenuBase.RunEffectImpl(Type effectType) in D:\src\pdn\src\PaintDotNet\Menus\EffectMenuBase.cs:line 1231
   at PaintDotNet.Menus.EffectMenuBase.RunEffect(Type effectType) in D:\src\pdn\src\PaintDotNet\Menus\EffectMenuBase.cs:line 798
   at PaintDotNet.Menus.EffectMenuBase.OnEffectMenuItemClick(Object sender, EventArgs e) in D:\src\pdn\src\PaintDotNet\Menus\EffectMenuBase.cs:line 788
   at System.Windows.Forms.ToolStripItem.RaiseEvent(Object key, EventArgs e)
   at System.Windows.Forms.ToolStripMenuItem.OnClick(EventArgs e)
   at PaintDotNet.Menus.PdnMenuItem.OnClick(EventArgs e) in D:\src\pdn\src\PaintDotNet\Menus\PdnMenuItem.cs:line 305
   at System.Windows.Forms.ToolStripItem.HandleClick(EventArgs e)
   at System.Windows.Forms.ToolStripItem.HandleMouseUp(MouseEventArgs e)
   at System.Windows.Forms.ToolStripItem.FireEventInteractive(EventArgs e, ToolStripItemEventType met)
   at System.Windows.Forms.ToolStripItem.FireEvent(EventArgs e, ToolStripItemEventType met)
   at System.Windows.Forms.ToolStrip.OnMouseUp(MouseEventArgs mea)
   at System.Windows.Forms.ToolStripDropDown.OnMouseUp(MouseEventArgs mea)
   at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
   at System.Windows.Forms.Control.WndProc(Message& m)
   at System.Windows.Forms.ScrollableControl.WndProc(Message& m)
   at System.Windows.Forms.ToolStrip.WndProc(Message& m)
   at System.Windows.Forms.ToolStripDropDown.WndProc(Message& m)
   at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
   at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
   at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
 

 

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now