VERIFIED SOLUTION i

Working with Text in the 64-bit Layout

Working with Text in the 64-bit Layout

This is a continuation of several articles discussing MapBasic how-to topics for the 64-bit Layout window
(https://li360.pitneybowes.com/s/article/Working-with-Maps-in-the-64-bit-Layout,  https://li360.pitneybowes.com/s/article/Working-with-Legends-in-the-64-bit-Layout).  

All the examples assume you are working with a Layout Window using “layoutID” as the variable for the Layout’s window identifier, and that the Layout coordinates have been set to inches.

1. CREATING TEXT

To create text on the current page use the same MapBasic that is used to create text in a map. Additional clauses for frame border and background styles as well as frame Priority and Name are also supported just for creating text in a Layout.

Create Text [Into Window layout_window_id]
       text_string (x1, y1) [(x2, y2)]

       [Font...]  [Spacing {1.0 | 1.5 | 2.0}]

       [Justify {Left | Center | Right}] [Angle text_angle]

       [Pen ....] [Brush ...] [Priority n] [Name framename]

Starting with MapInfo Pro version 16.0.3, the (x2, y2) coordinate is optional in the Layout. Leaving it out allows you to create a text frame that is sized to fit the extents of the text based on the font being used. For example:

Create Text Into Window layoutID “This is some text" (1, 1) Font (“Arial”, 0, 12, 0)

1
Note that only a single position coordinate (1, 1) was specified in the MapBasic statement. When just the position is specified, the frame is created to exactly fit the extents of the text. Selecting the text frame shows that its bounds are set to the text extents.

To create text that has a fixed size frame add the 2nd set of coordinates that define the bounding box of the frame. Here’s an example that includes setting the angle of the text frame as well as text justification:

Create Text Into Window layoutID "This is some text" (1,1) (3,2) Font (“Arial”, 0, 12, 0) Justify Center Angle 340 Pen(1,2,0)

A border Pen clause was added to show visually that the bounds are defined by including both coordinates (1,1) (3,2).

2

2. EDITING TEXT FRAMES
You can change frame properties that are shared across all frame types by using Alter Designer Frame.

To edit common frame properties like position, size, name or angle:

Alter Designer Frame [Window layout_window_id]

    Id {frame_id}

    [Position (x, y) [Units paper_units]]

    [Height height [Units paper_units]]

    [Width width [Units paper_units]]

    [Name name]

    [Angle angle]

The [Angle angle] clause applies only to text, image, and symbol frame types.

Any frame can have a Name assigned to it. By default, empty frames are assigned the string “No Content”, but most other frame types are assigned an empty string as a default Name.  

Assigning a unique Name to a frame makes it easier to refer to it when using functions like LayoutItemInfo or LayoutPageItemInfo. Both these functions will take a string Name as argument instead of a numeric frame Id. However, you still need the numeric frame Id for statements like Alter Designer Frame or Alter Designer Text.

3. ALTER DESIGNER TEXT

Alter Designer Frame is used to edit common frame properties for all frame types. But to edit the string displayed in a text frame, or its font, use Alter Designer Text.

Alter Designer Text [Window layout_window_id]

     ID textframe_id

     Text text

     [Font...]

For example, modifying the 2nd text frame like this:

Alter Designer Text ID 2 Text “This is longer text that will be wrapped in this box.” Font (“Times New Roman”, 0, 14, 0) looks like this:

3

 

Note that since this frame was created with a fixed size, its width and height will not auto adjust to fit the text. The rendered text will be clipped if its extents exceed the width or height of the frame.

However, in the first example text frame we created, recall that we did not specify a fixed size. You can still modify the text of that frame and its size will auto size to fit the new text extents.  For example:

"Alter Designer Text ID 1 Text "This is longer text that will continue on the same line."

4

 

Similarly, if you make the text string shorter, the frame size is also now smaller:

Alter Designer Text ID 1 Text "This is text"

5

As long as the width or height of the frame has not been altered by MapBasic or manually, it will continue to auto adjust to the size of the current text extents.

4. SMART TEXT
Layout Smart Text is an enhancement to text frames in the Layout. Previously you could only add static text to text frames. With MapInfo Pro version 17.0, Smart Text lets you create text that dynamically updates based on the context.


There is a great example and explanation on Smart Text in this article: https://li360.pitneybowes.com/s/article/How-to-take-advantage-of-the-new-MapBasic-Exec-function-in-MapInfo-Pro

But here are a couple more common use cases.


4.1 DISPLAY MAP PROJECTION

Let’s say you have a map frame with the name “Map-1”. To display its current projection create a text frame with the following MapBasic:

Create Text Into Window layoutID "Projection: 
$mb{CoordSysName$(MapperInfo(LayoutItemInfo(CurContext(1), ""Map-1"", 5), 17))}" (3,3)

The Smart Text is embedded within the text string delimited by $mb{}:

$mb{CoordSysName$(MapperInfo(LayoutItemInfo(CurContext(1), "Map-1", 5), 17))}

It is a series of MapBasic function calls. Starting with the inner-most function:

  • CurContext(1) returns the layout window ID the text frame belongs to
  • LayoutItemInfo(CurContext(1), “Map-1”, 5) returns the window ID of the map contained in the frame named “Map-1” in the Layout window given by CurContext(1).
  • The return value of LayoutItemInfo is passed to MapperInfo with the attribute value 17 to get the coordinate system clause
  • Which in turn in passed to CoordSysName$ to return its friendly name.

You cannot use defined constants for attributes, you must use their numeric value in a Smart Text expression.

If you change the projection of the map, the text will automatically update. In this example, the result looks like the text outlined in red:

6

4.2 DISPLAY CARTOGRAPHIC SCALE

Another common use case, which will be available with MapInfo Pro version 17.0.1, is to display the cartographic scale of a map. In this example a Name has also been assigned to this frame so that we can use it in calls to LayoutItemInfo later.

Create Text   Into Window layoutID   "Scale $mb{MapperInfo(LayoutItemInfo(CurContext(1), ""Map-1"", 5), 33)}" (1,1) Name "CartoScale"

The Smart Text is:

$mb{Scale $mb{MapperInfo(LayoutItemInfo(CurContext(1), "Map-1", 5), 33)}

The call to LayoutItemInfo(CurContext(1), "Map-1", 5) is again returning the window ID of the map, and passing it to MapperInfo with a new attribute 33 (MAPPER_INFO_CARTO_SCALE_EXPR). The string returned will be formatted using the Regional settings for number formatting.

As you zoom your map or change its scale, the smart text will automatically update to show the current cartographic scale value.
 

7

5. SMART TEXT ATTRIBUTES FOR LAYOUTITEMINFO AND LAYOUTPAGEITEMINFO

With version 17.0 you can get access to the Smart Text strings in both their evaluated and un-evaluated forms.

LAYOUT_ITEM_INFO_TEXTSTRING (24)

  • Returns the raw text string assigned to the frame.

LAYOUT_ITEM_INFO_SMART_TEXTSTRING (25)

  • If the text contains Smart Text expressions, the evaluated return value of the expressions are returned within the string.

Using the text frame showing cartographic scale example (it was created with the Name “CartoScale”):

LayoutItemInfo(layoutID, “CartoScale”, 24)

returns:

“Scale $mb{MapperInfo(LayoutItemInfo(CurContext(1), "Map-1", 5), 33)}”

whereas:

LayoutItemInfo(layoutID, “CartoScale”, 25)

returns:

“Scale 1:10,590”

More common examples of Smart Text are included in one of the sample Layout Templates that ships with MapInfo Pro version 17.0, called “SmartText Title Block”.

For more details review the Layout Smart Text section in the MapInfo Pro User Guide, and search for “Smart Text” and the CurContext function in the MapBasic Reference Guide.

6. DELETING FRAMES

Removing frames from a Layout window is done using Remove Designer Frame.

Remove Designer Frame [Window layout_window_id]

     Id frame_id, frame_id, frame_id, ...

Using our current example, both text frames can be removed from the current page with this statement:

Remove Designer Frame Window layoutID ID 1,2

 

UPDATED:  July 25, 2018