Introduction

As part of the development team for Corel DESIGNER® 12, I and my colleagues restored the Outline Enhanced Pattern style from version 9 of the software. Although the current implementation does not allow this style to be customized from within the application, a dedicated user can manually create a custom enhanced pattern and format. This article describes how to do this, step by step.

Getting Started

On our team, we refer to the Outline Enhanced Pattern as the “Enhanced line style,” or ELS. ELS styles are stored in a file called coreldes.dot. This file is found in the Custom Data folder within the Corel DESIGNER installation folder. Despite its filename extension, this file is an XML file, which you can edit with Microsoft® Notepad, or any XML editor, as long as you have administrator privileges on your computer. Make sure that you modify the coreldes.dot file that is in \Corel DESIGNER Technical Suite X4\Custom Data, not the file with the same name that is in C:\Documents and Settings\<user>\Application Data\Corel\Corel DESIGNER Technical Suite X4\Custom Data. If you have already started and used Corel DESIGNER, you should delete coreldes.dot in the user folder so that the application is forced to work from the new file that you will be editing or creating. Before beginning to create a custom ELS, you should back up a copy of the coreldes.dot file that was shipped with the product.

In the process of creating a new ELS, you will frequently reload your Outline Enhanced Pattern list in Corel DESIGNER. This file is loaded automatically when you open the Outline Pen dialog box for the first time. You can edit the file while Corel DESIGNER is running, but you must restart the application to view your changes. Alternatively, you can use my little “Easter egg” to force Corel DESIGNER to quickly reload the DOT file and avoid having to restart the application:

  1. Open the Outline Pen dialog box.
  2. Hold down the Shift key.
  3. In the Pattern Style area, click Standard or Enhanced, whichever style was not previously selected.

You can easily test this out by modifying the first pattern in the file that looks like this:

<stdPattern>
  <dotLength>1</dotLength>
  <dotLength>1</dotLength>
</stdPattern>

This pattern corresponds to the first pattern in the Standard pattern list box:

Change the pattern as follows:

<stdPattern>
  <dotLength>9</dotLength>
  <dotLength>1</dotLength>
</stdPattern>

Save your file, and try clicking while holding down Shift. Now, the first pattern in your Standard list box should look like this:

Note that when you create a Corel DESIGNER file that contains your new patterns, the file will open normally on any other computer, because the pattern’s definitions are stored within the file. You need your custom DOT file only when you create a new Corel DESIGNER file that uses your custom patterns.

Now that you have a good editing workflow, we can explore the more interesting stuff.

ELS Overview

Take a look at the following drawing, which summarizes the essentials of ELS definition. The drawing gives you a visual context that will help you understand what you are about to read. The specific example of an ELS definition that appears in the drawing is described at the end of this document. Don’t try to understand everything from the drawing now. Just observe it for a minute, and then move on.

Notice the centered light-gray line. This line is the control curve, which corresponds to the curve on which you would apply the ELS in Corel DESIGNER. The light-gray rectangle around the control curve indicates the area within which your ELS should be defined. Although it is possible to define the ELS outside this area, doing so would cause screen-refresh issues in Corel DESIGNER. The area's height defined by the control curve corresponds to the specified pattern width in Corel DESIGNER.

  

Pattern Syntax Overview

You might have already noticed by observing your DOT file that there are two types of pattern: the “stdPattern” and the “enhPattern” (“std” indicates Standard, and “enh”  indicates Enhanced). Here are examples of both:

<stdPattern>
  <dotLength>5</dotLength>
  <dotLength>1</dotLength>
  <dotLength>1</dotLength>
  <dotLength>1</dotLength>
</stdPattern>

<!-- NES_HOLLOWDOT -->
<enhPattern>
 <wideline threadWidth="762" nbDivisions="1">
  <line start="0" height="1" divide="1" cap="255" join="255">
   <styleData hollow="true" bar="false">
    <styleLength>4</styleLength>
    <styleLength>4</styleLength>
   </styleData>
  </line>  
 </wideline>
</enhPattern>

<!-- NES_DIAMONDS -->
<enhPattern>
 <wideline threadWidth="762" nbDivisions="5">  
  <line start="0" height="5" divide="1" cap="255" join="255">
   <cyclicalData width="1" lineDivision="3">
    <stylePoint>0</stylePoint>
    <stylePoint>100</stylePoint>    
   </cyclicalData>
  </line>
  <line start="0" height="5" divide="1" cap="255" join="255">
   <cyclicalData width="1" lineDivision="3">
    <stylePoint>100</stylePoint>
    <stylePoint>0</stylePoint>    
   </cyclicalData>
  </line>
 </wideline>
</enhPattern>

Standard Pattern Syntax

Although this article is not about Standard pattern, I would like to mention that the stdPattern syntax is documented within the DOT file and is very simple. You can modify Standard pattern directly through the existing UI:

Enhanced Pattern Syntax

ELS has the following syntax:

[<!-- optional comment -->]
<enhPattern>
 <wideline threadWidth="n" nbDivisions="n">
  <line start="n" height="n" divide="n" cap="0|1|2" join="0|1|2">
   [
    <styleData hollow="true|false" bar="true|false">
     <styleLength>n</styleLength>+
    </styleData>
   ]
   |
   [
    <cyclicalData width="n" lineDivision="n">
     <stylePoint>n</stylePoint>+
    </cyclicalData>
   ]
  </line>+  
</wideline>
</enhPattern>

Syntax conventions:

Symbol

Meaning

[]

optional

+

1 or more times what precedes

|

OR

n

a number

 

Enhanced Pattern Reference

Different properties in ELS definitions require different line renderers, which are portions of code that interpret the line definitions and control curves that are used to plot the curve on-screen. The use of different line renderers can cause inconsistent behavior and make the ELS definition more difficult to understand.

In total, we have four different line renderers:

  • The cyclicalData line renderer is used when “cyclicalData” is specified.
  • The styleData line renderer is used when “styleData” is specified with hollow and bar set to “false.”
  • The ELS polyline line renderer is used when cyclicalData and styleData are absent, or when styleData is specified with hollow or bar set to “true.”
  • The Standard polyline line renderer is used for the Standard patterns. (Details about the Standard pattern are not included in this article.)

Unfortunately, parameters behave differently with different line renderers. For example, interpretation of the nbDivisions parameter differs between the cyclicalData line renderer and the styleData line renderer.

wideline

You must have one wideline element per ELS pattern definition. In the future, we might have other types of enhanced pattern, but for now, we have only wideline. A wideline consists of a set of lines.

line

You can have as many line elements as you want within a wideline.

threadWidth

The threadWidth value specifies the pen width in tenths of a micron. Keep this value at 762, which corresponds to what used to be the outline width of the cyclical line. The threadWidth value is now ignored, because it is overruled by the outline width that you set in the Outline Pen dialog box of Corel DESIGNER.

cyclicalData

The cyclicalData properties are used to define a line pattern that consists of cycles. Imagine lines that are drawn by a seismograph and have no gaps. Here are some examples:

You can have one or more lines with cyclicalData information.

nbDivisions

Here is an example of how the ELS pattern width is divided when you specify cyclicalData information for a line. If you set a pattern width of 10 mm on the UI and you set nbDivisions to 10, then your ELS pattern width is divided like this:

This information will make more sense as you read on further.

start

In this case, the start value represents where your line starts. It is a 0-based index. In my example, this value can range from 0 to 10, but it cannot be fractional.

height

The height value is the height of your line expressed in number of divisions. Along with the start value, it defines your line pattern height, width, and area. Again, this value cannot be fractional. For example, if you have a start value of 1 and a height of 3, then your line cyclical data is rendered within this area and repeated indefinitely.

stylePoint

Now, let’s add some stylePoint values. The cyclicalData consists of a list of stylePoint values. You can have as many of these values as you want. The stylePoint values represent the actual pattern and are a sequence of integers that represent percentages. They range from 0 to 100 and cannot be fractional. A value of 0 means that the stylePoint is at the top of the line pattern area, and a value of 100 means that the stylePoint is at the bottom of the line pattern area. The last stylePoint is always implicit, and it corresponds to the first stylePoint value. This means that you cannot have gaps when you use cyclicalData. The “horizontal” location of the stylePoint values depends on the number of stylePointvalues you have, because they are all scaled to fit the line pattern width. For example, if you have the stylePoint values 10, 30, and 75, your pattern will look like this:

width

You can change the width to scale your cyclicalData values horizontally. The width property is a multiplier that can range from 1 to n and cannot be fractional. The line pattern width is always a multiple of the line pattern height. For example, if you take the above example and set a width of 2, your pattern will look like the following:

divide

You can also divide your pattern height by specifying the divide value. The divide value can range from 1 to n and cannot be fractional. This value is a scaling factor that can be used to proportionally shrink your pattern around its center line by a given percentage. Specifying this value is the only way that you can avoid having a pattern height fall exactly on a division line. For example, setting a divide value of 2 causes the pattern to be 1/2 or 50% of its original size.

lineDivision

The lineDivision value is ignored. Keep the setting at 1.

cap

The cap value is ignored. Keep the setting at 255. Cyclical lines do not support line caps. The UI values are not used for cyclical lines.

join

The join value is ignored. Keep the setting at 255. Cyclical lines do not support line join. The UI values, called Corners, are not used for cyclical lines.

figurePoint

The figurePoint properties are not used, so you can discard these values.

styleData with hollow and bar set to “false”

In this case, the styleData properties are used to define a line pattern consisting of dashes. Here are some examples:

You can have as many lines with styleData as you want, but you must have at least two lines.

hollow and bar

Both hollow and bar must be set to “false.”

nbDivisions

When you specify styleData information for a line, the nbDivisions value specifies how the ELS Pattern Width is divided. For example, if you set a pattern width of 10 mm on the UI, and you set nbDivisions to 10, then your ELS pattern width is divided like this:

Again, this will make more sense as you keep reading.

start

In this case, the start value represents where your line lands. It is a 0-based index. Consequently, in my example, its value can range from 0 to 9, and it cannot be fractional. For example, if you have a start value of 1, then your line style data will be rendered on this line and repeated indefinitely.

height

The height value has no practical use in this case.

styleLength

The styleData information consists of a list of styleLength values. The styleLength values represent the actual pattern and are a sequence of integers that must each be a multiple of 4 — that is, 0, 4, 8, 12, 16, 20, and so on. When you divide each value by 4, you get a multiplier that you apply to the ELS pattern height to obtain the dash’s length. The dashes alternate: The first one is opaque, the second is transparent, the third is opaque, and so on. If you want to start with a transparent dash, just set the first styleLength value to 0. Yes, you can have as many styleLength values as you want, but note that the pattern itself will alternate if you have an odd number of styleLength values. For example, think of the pattern 4-12-8. If I put the opaque dashes in bold, I end up with 4-12-8-4-12-8-4-12-8-4-12-8, not 4-12-8-4-12-8-4-12-8 as you would expect. Let’s look at the result. We have to have at least two lines, so I created the pattern 4-12-8 with two different start values: 1 and 8. This gives us the following:

If the ELS pattern height is 10 mm, then the length of the first dash is 4/4 × 10 mm = 10 mm. The second dash, which is transparent, is 12/4 × 10 mm = 30 mm in length and the third one is 20 mm. Consequently, the smaller your ELS pattern height value is, the shorter your pattern will be.

divide

The divide value has no effect.

cap

The cap value has no effect. It is superseded by the value provided by the UI.

join

The join value has no effect. It is superseded by the value provided by the UI, called Corners.

styleData with hollow or bar set to “true”

In this case, the styleData properties are used to define a line pattern that consists of hollow dashes. Here are some examples:

When hollow is set to “true,” you can have one or more lines in the styleData information, unlike when hollow is set to “false,” in which case you need at least two lines (see earlier).

hollow and bar

The hollow and bar properties control the same behavior. When the hollow property is set to “true,” everything changes. That’s why I created two sections for styleData and why I discuss each case separately. You can use one of these properties, but both properties must be set to “false” to turn off the hollow property. Only one of these properties must be set to “true” to turn on the hollow property.

nbDivision

With hollowing, when you specify styleData information for a line, the nbDivisions value specifies how the ELS Pattern Width is divided. For example, if you set a pattern width of 10 mm (on the UI) and nbDivisions to 10, your ELS pattern width is divided like this:

As you read on, this will make more sense.

start

In this case, the start value represents where your line starts. It is a 0-based index. Consequently, in my example, its value can range from 0 to 10, and it cannot be fractional.

height

The height value is the height of your line (hollow dashes) in number of divisions. Again, this value cannot be fractional. For example, if you have a start value of 1 and a height of 3, then your styleData line with hollowing will be rendered within this area and will be repeated indefinitely:

styleLength

The styleLength values represent the actual pattern and are a sequence of integers that must be multiples of 4.

The styleLength behavior depends on the type of cap specified (see next section).

cap

Unlike the other cases, the cap value specified in the DOT file overrides the value on the UI. Therefore, you can have multiple hollowed lines with different line caps.

If the cap is set to 0 (round), the length of the dash, excluding the round cap, will be (styleLength – 4)/4 × 1/2 ELS pattern Height. For example, if we use styleLength 8-8 with an ELS pattern height of 10 mm, we have a hollowed dash with a length of (8 – 4)/4 × 5 mm = 5 mm. For the space separating the dashes, which includes the cap, the formula is space = styleLength/4 × 2 × ELS pattern height. In our example, the space styleLength is 8. Therefore, the actual length will be 8/4 × 2 × 10 mm = 40 mm. Do you agree that this makes no sense? Let’s look at our example:

If the cap is set to 1 (no cap), then it is simpler. In this case, styleLength functions the same as if you have hollow set to “false.” Consequently, in our example, the dash and the space are of the same length, and given that 8/4 = 2, the length is 2 × 10 mm = 20 mm. Let’s look this example:

If the cap is set to 2 (square cap), then it is similar to the no cap case. In this case, the space does not include the square cap. Unfortunately, a limitation affects the use of square caps in my earlier example, and it produces unexplainable results. Here is a new example, in which the styleLength values are set to 4-4, the start value is set to 0, and the height is set to 10. We therefore obtain the following:

If the cap is set to anything other than 0, 1, or 2, then the value that is taken from the UI determines which of the three previously described behaviors will apply.

join

The join value is ignored and has no effect. Changing it through the UI does not change the result.

divide

The divide value has no effect.

Example 1

Now, let’s take another look at the example shown at the beginning of this article:

Consider the first custom example in the upper-right corner of the picture, the one named “Left Example.” We will go through this example here. The others are custom enhanced line styles that I created.

Our example is an ELS pattern that consists of three lines. The zigzag is a cyclicalData line, and the dashed line is a styleData line with no hollowing. The line is, well, a line.

Here is the XML code that represents this ELS:

<!-- NES_LEFTEXAMPLE -->
<enhPattern>
  <wideline threadWidth="762" nbDivisions="10">
    <line start="1" height="3" divide="1" cap="255" join="255">
      <cyclicalData width="2" lineDivision="3">
        <stylePoint>80</stylePoint>
        <stylePoint>20</stylePoint>
      </cyclicalData>
    </line>
    <line start="7" height="1" divide="1" cap="255" join="255">
      <styleData hollow="false" bar="false">
        <styleLength>4</styleLength>
        <styleLength>8</styleLength>
      </styleData>
    </line>
    <line start="6" height="1" divide="1" cap="255" join="255">
    </line>
  </wideline>
</enhPattern>

Notice that there are three lines that define this wideline.

The first line uses cyclical data to represent a zigzag pattern that oscillates between the tops of divisions 1 and 4. Take a look at the “Cyclical Line” section to see how the values are interpreted.

The second line uses style data to represent a dash pattern that is lined up with the top of division 7. Look at the “Style Line and Simple Line” section to see how the values are interpreted.

The third line is a simple line and is just lined up with the top of division 6.

Example 2

For those of you who noticed that the “Geschlossener” example has vertical segments and wonder why I said that you could not do that, here is the explanation. First, if you could zoom in close enough, you would notice that these segments are not quite vertical. I produced this vertical appearance by specifying 134 style points. Given that all the style points would be drawn at an equal distance from each other, and they all would be drawn within the cyclicalData width, I specified 133 points to represent the 45-degree slope (when two points would have been enough) and 1 point to have the cyclical line drop to the bottom right away. (This is a simplified explanation of what I did.) This method can work in some cases, but it leads to an extremely slow rendering time.

Here is a less complicated example:

<!-- NES_STRAITEXAMPLE -->
<enhPattern >
      <wideline threadWidth="762" nbDivisions="10">              
            <line start="0" height="10" divide="1" cap="255" join="255">
                  <cyclicalData width="1" lineDivision="1">
                        <stylePoint>0</stylePoint>
                        ... 98 mores ...
                        <stylePoint>0</stylePoint>
                        <stylePoint>100</stylePoint>
                        ... 98 mores ...
                        <stylePoint>100</stylePoint>
                  </cyclicalData>
            </line>
      </wideline>
</enhPattern>

The results are represented here:

Example 3

I spent hours trying to figure out a way to create an ELS that looks like a railroad. Here is the best I could come up with:

I’ll zoom in to give you a hint of how I did it!

Can you figure it out?

Limitations

Unfortunately, not everything can be represented with the current ELS specification.

  • Lines can only go forward. There is no way to represent lines that go backward.
  • Cyclical line styles must be contiguous. There is no way to represent gap.
  • There is no way to represent vertical lines.

Conclusion

Defining a custom ELS can be challenging. Nevertheless, a custom ELS lets you create unique technical documents that better represent what you are illustrating.

This feature can unleash your creativity and take your technical drawing illustrations to the next level!