Jump to content
How to Install Plugins ×

Arc Text (May 13, 2022)


VeLC

Recommended Posts

Draws text along an arc

 

Screenshot-ArcText.thumb.png.95129559871ca56b8d05eada63ffafc7.png

 

This is basically dpy's Circle Text plugin with a different UI and better math for proportional fonts

Also in Effects > Text Formations

 

Versions:

1.0(20220418) - Initial Release

1.1(20220420) - Now works with selection and slightly shorter UI

1.2(20220421) - Update code to make it compatible with CodeLab v6.1 (and below?). Also, detects if user canceled.

1.3(20220428) - Now works faster if there are multiple selections

1.4(20220506) - Fix space character not rendering when Character Spacing is zero and slightly shorter UI

1.5(20220513) - Code Update and slightly shorter UI

 

CodeLab Code

License: LPGL-3.0

 

Spoiler
// Name: Arc Text
// Submenu: Text Formations
// Author: Louie Velarde
// Title: Arc Text
// Version: 1.5
// Desc: Draws text along an arc
// Keywords: arc text|circle text|circular text
// URL: https://forums.getpaint.net/topic/119904-arc-text/
// Help: https://forums.getpaint.net/topic/119904-arc-text/
// Force Single Render Call
#region UICode
TextboxControl text = ""; // [3600]
IntSliderControl repeat = 1; // [1,360] Repeat
FontFamily fontFamily = new FontFamily("Arial"); // 
IntSliderControl fontSize = 12; // [8,288] 
CheckboxControl bold = false; // Bold
PanSliderControl center = Pair.Create(0.000, 0.000); // Center
ListBoxControl alignment = 0; // |Start Position|Center Position|End Position
AngleControl position = 135; // [0,360] 
CheckboxControl clockwise = true; // Clockwise
CheckboxControl useAngle = true; // Calculate character spacing based on arc angle
CheckboxControl endSpace = false; // Append space after last character
IntSliderControl charSpacing = 0; // [0,100] {!useAngle} Character Spacing
IntSliderControl angle = 90; // [0,360] {useAngle} Arc Angle
IntSliderControl radius = 150; // [1,1000] Arc Radius
#endregion

bool rendered;

void PreRender(Surface dst, Surface src)
{
    rendered = false;
}

void Render(Surface dst, Surface src, Rectangle rect)
{
    if (rendered) return;
    rendered = true;

    rect = EnvironmentParameters.SelectionBounds;
    dst.CopySurface(src, rect.Location, rect);

    if (text == string.Empty) return;
    
    StringBuilder line = new StringBuilder(text);
    for (int i = 2; i <= repeat; ++i)
    {
        if (IsCancelRequested) return;
        line.Append(text);
    }
    using (Graphics g = new RenderArgs(dst).Graphics)
    using (Region gClipRegion = new Region(rect))
    using (Font font = new Font(fontFamily, fontSize, bold ? FontStyle.Bold : FontStyle.Regular))
    using (Brush brush = new SolidBrush(EnvironmentParameters.PrimaryColor))
    {
        g.Clip = gClipRegion;
        g.SmoothingMode = SmoothingMode.AntiAlias;
        g.TextRenderingHint = TextRenderingHint.AntiAlias;

        double translateX = rect.Left + (center.First + 1) / 2 * rect.Width;
        double translateY = rect.Top + (center.Second + 1) / 2 * rect.Height;
        g.TranslateTransform((float) translateX, (float) translateY);

        StringFormat format = new StringFormat(StringFormat.GenericTypographic);
        format.FormatFlags |= StringFormatFlags.MeasureTrailingSpaces;
        format.FormatFlags |= StringFormatFlags.NoFontFallback;

        SizeF[] sizes = new SizeF[line.Length];
        double totalWidths = 0;
        double totalHeights = 0;

        for (int i = 0; i < line.Length; ++i)
        {
            if (IsCancelRequested) return;
            sizes[i] = g.MeasureString(line[i].ToString(), font, short.MaxValue, format);
            totalWidths += sizes[i].Width;
            totalHeights += sizes[i].Height;
        }
        double height = totalHeights / line.Length;

        double arcLength;
        if (useAngle)
        {
            arcLength = Math.PI * radius * angle / 180;
        }
        else
        {
            arcLength = totalWidths + charSpacing * (line.Length - 1);
            if (endSpace) arcLength += charSpacing;
        }
        double arcAngle = arcLength * 180 / Math.PI / radius;
        double spaceLength = (arcLength - totalWidths) / (line.Length - (endSpace ? 0 : 1));
        double spaceAngle = spaceLength * 180 / Math.PI / radius;

        int s = clockwise ? 1 : -1;

        switch (alignment)
        {
            case 0: g.RotateTransform((float) (s * 90 - position)); break;
            case 1: g.RotateTransform((float) (s * 90 - position - s * arcAngle / 2)); break;
            case 2: g.RotateTransform((float) (s * 90 - position - s * arcAngle)); break;
        }
        double halfCharAngle = sizes[0].Width * s * 90 / Math.PI / radius;
        g.RotateTransform((float) (halfCharAngle));

        float y = (float) (clockwise ? -radius : radius - height);
        g.DrawString(line[0].ToString(), font, brush, sizes[0].Width / -2, y, format);

        for (int i = 1; i < line.Length; ++i)
        {
            if (IsCancelRequested) return;
            g.RotateTransform((float) (halfCharAngle + s * spaceAngle));
            halfCharAngle = sizes[i].Width * s * 90 / Math.PI / radius;
            g.RotateTransform((float) (halfCharAngle));
            g.DrawString(line[i].ToString(), font, brush, sizes[i].Width / -2, y, format);
        }
    }
}

 

 

ArcText.zip

 

Edited by VeLC
Version 1.5
  • Like 6
  • Upvote 3
Link to comment
Share on other sites

Thanks! Question though. I see that in your ArcText.zip file the velc.ArcText.dll has file size 15872 and the install batch file has size 2842.

 

I copied your code and placed in CodeLab and built the effect to ArcText.zip (on my desktop) and see the file sizes have changed to ArcText.dll == 15360 and the install batch file to 2832.

 

Is there any reason? Is it due to .NET call differences? (version 6.0.3)??

 

Just asking. Works though. 👍

 

edit: figured the batch file sizes (velc.)

Edited by Panchdara
Link to comment
Share on other sites

  • VeLC changed the title to Arc Text (Apr 20, 2022)

If Repeat>1 the text disappears.

I used another variable (txt) to make it work. (CodeLab v6.1)

 

StringBuilder sb = new StringBuilder(text);
    for (int i = 2; i <= repeat; ++i)
    {
        sb.Append(text);
    }
string txt = sb.ToString();

 

Link to comment
Share on other sites

  • VeLC changed the title to Arc Text (Apr 21, 2022)
  • VeLC changed the title to Arc Text (Apr 28, 2022)
  • VeLC changed the title to Arc Text (May 6, 2022)
  • VeLC changed the title to Arc Text (May 13, 2022)
  • 1 month later...
  • 1 year later...

@Pixey Do you see what you did? Pointing to yourself?

Codelab now rejects the posted CS script with 4 errors. Could someone take the time to correct it please? I did half.

     double translateX = rect.Left + (center.First + 1) / 2 * rect.Width;
     double translateY = rect.Top + (center.Second + 1) / 2 * rect.Height;

These posted scripts are valuable lessons to demonstrate plugin development.

(My New Signature) Nickpic was a image hosting source made specifically for RPers and its shutting down. 

I use postimage.IO for free web hosting. How long before they follow photobucket and NicKPic?

Link to comment
Share on other sites

37 minutes ago, AndrewDavid said:

Do you see what you did? Pointing to yourself?

 

😁 Silly me - I was jumping between posts and didn't notice 😂

30b8T8B.gif

How I made Jennifer & Halle in Paint.net

My Gallery | My Deviant Art

"Rescuing one animal may not change the world, but for that animal their world is changed forever!" anon.

 
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...