[go: up one dir, main page]

0% found this document useful (0 votes)
116 views336 pages

OS2 Presentation Manager

This document provides a programming guide for using the OS/2 Presentation Manager Graphics Programming Interface (GPI) to output text, graphics, and printing. The GPI allows applications to draw primitives like lines, arcs, and areas to various output devices like display windows and printers. It covers key concepts like presentation spaces, device contexts, attributes, coordinates, and different drawing functions. The guide explains the GPI graphics model and rules for retained and non-retained graphics. It also provides details on functions for creating graphics, manipulating attributes, and drawing different primitives.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
116 views336 pages

OS2 Presentation Manager

This document provides a programming guide for using the OS/2 Presentation Manager Graphics Programming Interface (GPI) to output text, graphics, and printing. The GPI allows applications to draw primitives like lines, arcs, and areas to various output devices like display windows and printers. It covers key concepts like presentation spaces, device contexts, attributes, coordinates, and different drawing functions. The guide explains the GPI graphics model and rules for retained and non-retained graphics. It also provides details on functions for creating graphics, manipulating attributes, and drawing different primitives.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 336

=--

- Graham C.E. Winn

0S/2 PRESENTATION MANAGER GPI


-
==
-
=
-=
= AProgramming Guide
to Text, Graphics, and Printing
'

= PYRRMIDS .... <


fi le fdit !ransform ~rrange Qisplay §_pecial
2
:a
n
Cl
3
"Cl
C
C't
CD
.,
. r-
-·er
.,
.,DJ
mDOS 0S12 Full Screen
~
Group• Main
<
OS/2 Presentation Manager GPI
A Programming Guide to Text, Graphics, and Printing

Graham C. E. Winn

VAN NOSTRAND REINHOLD


',I,:,
New York

Rvffi\S?# a !K:: - ELJ a ELi !k3 iE€! A,f:BRA Fed?i i E-= |€iB
To Chris, Caroline, and Duncan

The Programs and Information Contained in this Book


The copyright in the sample computer programs included in this book is owned by International Business
Machines Corporation. The sample computer programs may be included within larger computer programs for
private or commercial use. International Business Machines Corporation accepts no responsibility for the
accuracy, operability, or suitability for any purpose of the sample computer programs.
While every effort has been made to ensure accuracy, the author and publisher accept no responsibility for the
accuracy, operability, or suitability for any purpose of the sample computer programs and information contained
in this book, neither is any liability assumed for damages resulting from the use of any information contained
herein.
Copyright © 1991 by Van Nostrand Reinhold

Library of Congress Catalog Card Number 91-3772


ISBN 0-442-cO739-6

AIl rights reserved. No part of this work covered by the copyright hereon may be
reproduced or used in any form or by any means-graphic, electronic, or mechanical,
including photocopying, recording, taping, or information storage and retrieval
systems--without written permission of the publisher.
Manufactured in the United States of America
Published by Van Nostrand Reinhold
115 Fifth Avenue
New York, New York 10003
M]/ 7DE]Eli DDli
Chapman and Hall
2rfe Boundny Row
I.ondon, SE 1 8HN, England

Thomas Nelson Australia


QA 76*76 w0631+.15651991
102 Dodds Street
South Melbourne 3205
Victoria, Australia L`Jirin, G`rcham Cu E*
Nelson Canada
1120 Birchmount Road 05/2 p`resentatioT`i maTiager
Scarborough, Ontario MIK 5G4, Canada GPI
16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1

Library of Congress Cataloging-in-Pulblication Data


Wim, Graham C. E.
OSA presentation manager GPI : a programming guide to text,
graphics, and printing / Graham C.E. Winn.
P. On.
Includes bibliographical reference and index.
ISBN 0-442-cO739-6
1. OSA (Computer operating system) 2. Fkesentation manager
(Computer program) I. Title.
QA76.76.063W665 1991
055.4'469ndc20 91-3772
CIP
Contents

Preface xl

Acknowledgments x]l[

Trademarks xw

Chapterl lnfroduct]oh: S]mpleTextand Graph]esoutput 1


GPI GRAPHICS SUBSYSTEM STRUCTURE 1
PRESENTATION SPACES AND DEVICE CONTEXTS 2
OUTPUT TO ADISPLAY WINDOW AND PRINTER 3
0UTPUITINGATEXTFILE 4
SIMPLE GRAPHICS OUTPUT 5
Drawing frimitives and Attributes 5
Simple 'Thansformations 6
RULESANDCONCEFTS 7
The GPI Graphics Model: Picture and EnvironmentAlesources
7
Retained and Non-Retained Graphics 8
CoITelation and Boundary Accumulation 8
Coordinates 9
GPI Coordinate Limits 9
Retained segment and MetaFile coordinate Limits 9
Rectangle Boundaries 10
Staying Responsive and Multi-threaded Applications 10
FIXED Nunibers 10
ErrorHandiing 11

Chapter 2 Presehtatlon spaces and Devlce conte)ds 41


DEVICE CONTEXTS 41

iii
iv CONTENTS

DisplaywindowDCs 41
QueuedDCs 42
DirectDCs 42
InfoDCs 42
MetaFileDCs 42
MemoryDCs 43
PRESENTATION SPACES 43
Micro-PS 43
Normal-PS 43
CachedMicro-PS 43
PS CREATIONAND ASSOCIATION 44
GPI SETPS 46
surm4ARy OF ps AND Dc CREATION AND
ASSOCIATION 46
DisplaywindowDC 46
Non-Display window DC 46
Normal-Ps or uncached Micro-PS 46
Association of DC and a Normal-PS or an uncached
Micro-PS 46
Allocatiorroe-Allocation of cached Micro-PS/DC pair for a
window 46
Allocatiolroe-Allocation of cached Micro-Psroc for
WM_PAINT processing 46
Use of an existing PS and associated window DC for
WM_PAINT processing 47
Allocation and De-Allocation of cached Micro-Psroc pair for
thedesktop 47
GPICREATEPS IIARAMETERS 47
hab 47
hdc 47
psizlps 47
floptions 48
Retumvalue 49
PS AND DC CONTROLAND QUERY FUNCTIONS 49
DevEscape 49
DevQuerycaps 50
GpiErase 50
GpiQueryDevice 50
Gpikesetps 50
Gpisaveps/GpiFlestoreps 50

Chapter 3 Drawlng pr[mltlves and Attr]butes 59


ATrRIBUTh s 59
Bundle Attributes 59
Non-Bundle Attributes 61
CONTENTS V

Attribute Mode and Attribute popping 62


DefaultAttributes 63
Attribute Querying 64
Attribute Resetting 64
TEXT AND CIIARACThR FUNCTIONS 65
Character Bundle Attributes 65
lcolor (CBB_COLOR) 65
lBackcolor (CBB_BACK_COLOR) 65
usMixMode (CBB_MIX_MODE) 65
usBackMixMode (CBB_BACK_MIX_MODE) 66
usset(CBB_SET) 66
usHecision (CBB_MODE) 66
sizfxcell (CBB_BOX) 66
ptlchgle (CBB_ANGLE) 67
ptlshear (CBB_SREAR) 68
usDirection (CBB_DIRECTION) 69
Character string Himitives 70
Char Extra andBreak Extra spacing 70
LINE drD CURVE FUN-cTIONs 71
Line Bundle Attributes 71
lcolor qBB_COLOR) 71
usMixMode qBB_MIX_MODE) 71
fxwidth qBB_WIDTID 71
lGeomwidth qBB_GEOM_WIDTID 71
usType qBB_TYPE) 71
usEndqBB_END) 72
usJoin qBB_JOIN) 72
Line and cur've Hrimitive Functions 72
GpiLine 72
GpipolyLine 72
GpipolyFillet 73
GpipolyFilletshaxp 73
Gpipolyspline 73
GpiFuildrc 73
Gpipartialdrc 75
GpipointArc 75
GpiBox 75
Gpioutlinepath 76
Arc parameters 76
Gpisetpel and GpiQuerypel 79
AREADRAWING FUNCTIONS 79
Area Bundle Attributes 79
lcolor (ABB_COLOR) 79
lBackcolor (ABB_BACK_COLOR) 79
usMixMode (ABB_MIX_MODE) 79
usBackMixMode (ABB_BACK_MIX_MODE) 79
VI CONTENTS

usset(ABB_SET) 79
ussymbol (ABB_SYMBOL) 80
ptlRefpoint (ABB_REF_POINT) 80
AreaHimitives 81
MARKERFUNCTIONS 82
Marker Bundle Attributes 82
lcolor orBB_COLOR) 82
lBackcolor orBB_BACK_COLOR) 82
usMixMode orBB_MIX_MODE) 82
usBackMixMode orBB_BACK_MIX_MODE) 83
ussetorBB_SET) 83
ussymbol orBB_SYMBOL) 83
sizfxcell orBB_BOX) 83
Marker Himitives 84
GpiMarker 84
GpipolyMarker 84
IMAGE AND BITBLTFUNCTIONS 84
Image Bundle Attributes 84
lcolor (IBB_COLOR) 84
lBackcolor (IBB_BACK_COLOR) 84
usMixMode (IBB_MIX_MODE) 85
usBackMixMode (IBB_BACK_MIX_MODE) 85
Image and BitBlt Drawing llrimitives 85
Gpilmage 85
GpiBitBit 85
GpiwcBitBlt 89
PATH S 90
Geometric wide Line Attributes (used with paths) 90
lGeomwidth (LBB_GEOM_WIDTH) 90
usEnd (LBB_END) 90
usJoin (LBB_JOIN) 91
Path Definition 91
Pathdreas 92
Pathoutlines 93
Geometric wide Lines 93
Clippaths 94

Chapter4 Fonts 98
PUBLIC AND PRIVATE FONTS 100
MONOSPACED AND PROPORTIONAL FONTS 101
RASTERAND OUTLINE FONTS 101
FONT METRICS 104
FONT SELECTION AND LOGICAL FONT CREATION 107
CONTENTS vii

OUTLINE For`IT SCALING uslNG cllARACTER


BOXAITRIBUTE 109
GPIANDFONTCODEPAGES 111
BITMAPSETIDS 112

Chapter5 B[tmaps 126


BITMAPFORMATS 126
BITMAP CREATION AND DELETION 128
GpicreateBitmap 128
Gpil.oadBitmap 128
WinLoadpointer 128
GpiDeleteBitmap 129
BITMAPSELECTION 129
BITMAP DATAFORMAT AND DATATRANSFER 129
BITMAP DIMENSION FUNCTIONS 131
BITMAPAND BITBLT EXAMPLES 131

0hapter6 ColorTables 143


THE STANDARD COLORTABLE 143
LOGICAL COLOR TABLE CREATION 145
LCOLF RGB 146
LCOLF INDRGB 146
LCOLF-CONSECRGB 146
LCOL RESET 146
Lcori REALIZABLE 146
LCOLF-PURECOLOR 147
REALIZABLE COLOR TABIIES 147
COLORQUERIES 148
GpiQueryljogcolorTable 148
GpiQuerycolorData 148
GpiQueryRealcolors 148
GpiQueryNearestcolor 148
GpiQuerycolorlndex 148
GpiQueryRGBColor 148

Chapter7 Coordlnate spaces andTransformatlon 150


PAGE UNITS 153
PRESENTATION SPACE TRANSFORMS 154
TRANSFORM REPI.ACE 156
TENSFORM-ADD 156
TRANSFORM-PREEMFT 156
MATRIX RARAME-TER FORMATS 157
COORDINATE LIMITS 157
GPICONVERT 158
A DETAILED DESCRIFTION OF THE TRANSFORMS 158
viii CONTENTS

Model 'Thansfo]rmi 158


Viewing 'Thansfo]m 161
Default viewing 'Thansform 162
Device 'Thansform. 163
Device 'Thansform. 'Thanslation Removal 165

Chapter8 CI]pplngAndReg[ons 168


APPLICATION CLIPPING FUNCTIONS 168
ViewingLimits 168
Graphics Field 168
Clippath 169
ClipFlegion 169
REGIONS AND CLIPREGIONS 169
Region Functions 170
Clip Region Functions 170
Region complexity 171

Chapter9 Orders, Elements, andsegments 172


DRAWINGORDERS 172
Fixed 1-Byte orders 172
Fixed 2-Byte orders 173
I.ongorders 173
Extended orders 174
Order Buffers 175
ELEMENTS 176
GRAPHICS SEGMENTS 176
CIIAINED AND CALLED SEGMENTS 179
DRAWINGMODES 180
SEGMENTAITRIBUTES 181
ATrR DETECTABIE 181
ATrR-vlslBLE 182
ATI`R-CHAINED 182
AITR-DENAMIC 182
AITR-FASTCRAIN 182
ATTR-PROP DETECTABLE 182
ATrR-pRop-vlslBLE 182
SEGMENTS WIT-HZERO ID 182
NON-RETAINED SEGMENTS 183
DRAWCONTROLS 183
DCTL ERASE 184
DCTL-DISPLAY 184
DCTL-BouroARy 184
DCTh DYNAMIC 184
DCTL-CORREI+ATE 184
STOP DRAW 184
CONTENTS lx

DYNAMIC SEGMENTS 185


SEGMENTEDITING 186
WHOLE SEGMENT EDITING FUNCTIONS 187

Chapter lo Correlatlon and Boundary Data Aceumulat]on 190


CORRELATION 190
Non-Retained correlation 190
Retained correlation 191
BOUNDARY ACCUMUIIATION 194

Chapterll MetaFIIes 195


TIRE METAFIIH FUNCTIONS 195
GPIPLAYRETAFILE 196
PMF SEGBASE 196
PMF LOADTYPE 196
PMF RESOLVE 197
PMF-LCIDS 197
PMF RESET 197
PIT SUPPRESS 197
PMF-COLORTABIuES 198
PMF COLOREALIZABLE 198
PMF-DEFAULTS 199
METAFIIIE PRINTING AND METAFILE TO METAFILE
RECORDING 199
SCALING AMETAFILE TO FIT AN OUTPUT AREA 199
DISPLAYING AMETAFILE AS A SUB-PICTURE 200
METAFIIIE RESTRICTIONS AND ESCAPE ORDERS 200
PIF FILES AND PICTURE FUNCTION CALLS 204

Chapterl2 Prlnt]ng 219


DIRECT PRINTING a)C TYPE: OD_DIRECT) 219
QUEUED PRINTING @C TYPE: OD_QUEUED) 220
TYPES OF PRINTING 220
Base control Hogram Hinting 220
FTesentation Manager Hinting 221
Spooler (Spl) Function calls (Spooler API) 222
0SA PRINT SUBSYSTEM 222
PRINTER INSTALI.ATION AND SET UP 224
NETWORK PRINTING 225
PRESENTATION MANAGER PRINTING FROM AN
APPLICATION 227
Establishing the Queue, Port, Driver, Device, and
DRIVDATA 228
P+inter selection Method 228
X CONTENTS

Queue selection Method 230


Opening the Dc and Hinting 231
FORM SELECTION 232
PRII`IT QUEUE PROCESSOR (QUEUE DRIVER)
SELECTION 232
PM_Q_STD PRINTING RESTRICTIONS 233
PRIRERFONTS 234
BITMAPAND nmTAFILE PRINTING 235
DOSPRINT SPOOLERAPI 235

Chapter 13 The os/2 2.032-BItoperatlng system 255

APPENDIX 1 DevopehDC parame(ers 257


hab 257
1Type 257
pszToken 258
1Count 258
pdopData 258
hdc 262

APPENDIX 2 PMPRIHT Queue processor parameters 263

APPENDIX 3 Introductlon to Transforms and Matrlces 267

APPENDIX4 Sample MetaFIIe lnternals 272

APPEHDIX5 Sampleorders 283

APPEHDIX6 GPI Functlons supported only by a Normal-PS 297

References and Blbllography 300

Glossary 301

Index 313
Preface

The OSATM I+esentation ManagerTM provides a rich and powerful set of applica-
tion programming interfaces which, to a newcomer, can appear rather complex
and confusing. Many Ospe application developers use software tools (such as
application generators) or languages which shield them from the complexities of
the application programming interface and serve as a useful productivity aid. The
ma].ority of these are designed specifically for text based applications that require
only the graphical user interface and it is currently necessary for programs to use
the Graphics Programming Interface directly in order to exploit the full graphics
capabilities of the OSA FTesentation Manager. This book is written for C program-
mers wishing to use the OSA I+esentation Manager GPI and Dev functions for
providing high quality te]it and graphics output to displays and printers. It is
intended to be used along with the relevant IBMTM and MicrosoftTM Reference
Manuals and Online Reference, and is not a substitute for these.
My aim in writing this book is, as far as possible, to provide answers
(illustrated by programming examples) to any questions that Application Devel-
opers may have concerning the GPI and Dev functions. Rather than providing a
tutorial description, I have concentrated on making the description of each topic
as comprehensive as possible. Chapter 1 provides an introduction and explains
how to output simple graphics and text to displays and printers. The remaining
chapters provide an in-depth description of each subject, illustrated where
appropriate by examples consisting of simple, self-contained program functions.
Also included in the main body of the text is a description of the underlying GPI
Architecture to assist readers in understanding a particular function.
Some familiarity with OSA Presentation Manager Hogramming funda-
mentals by the reader is assumed. The reader should, as a minimum, be able to
write a basic I}resentation Manager application in C to create a message queue
and standard window, with a window procedure that processes the messages.

xl
xii PREFACE

Although the main subject of this book is graphics, it is written for non-mathe-
maticians. Where mathematics is essential (e.g., in the treatment of transforms),
it is kept to a mininum. Both GPI and Dev functions are described, and where
there is overlap with other components (such as the Win and nrf functions), a
description of these is also provided.
This book is based on IBM OSA Version 1.3 and includes a discussion of Version
2.0.
Acknowledgment

I would like to thank my many friends and colleagues without whose knowledge,
help, support, encouragement, and willingness to review my work, this book would
not have been possible. I would like to give special thanks to the following people:
David Edwards, Heather Gill, Nick Goodall, Mike Jewson, Pete Johnson, Kelvin
Lawrence, Glyn Normington, Kate Robinson, Sushil Sharma, Robin Speed, Mike
Walker, Ken Wilson, and Ian Yorke-Smith. I would also like to thank IBM for
providing me with the opportunity and facilities to complete this work. Finally, I
would like to thank my family for their support and encouragement.

xiii
Trademarks

The following terms used in this publication are trademarks or registered trade-
marks of International Business Machines Corporation in the U.S.A. andyor other
countries:

IBM, OSA, I}resentation Manager

The following terms used in this publication are trademarks or registered


trademarks of other companies as follows:

IIf and IIASERJET Hewlett-Packard Company

Helvetica Linotype Company

Intel Intel Corporation

Microsoft Microsoft Corporation

Postscript and Adobe Systems Incorporated


Adobe Type Manager

Times New Roman Monotype Corporation Limited

QMS and QMS-PS QMS Incorporated

XV
Introduction: Simple Text and Graphics Output

This chapter describes how to generate simple GPI text and graphics output to
displays and printers, and introduces a number of important rules and concepts
required for the more advanced topics described in subsequent chapters.
The GPI (Graphics FTogramming Interface) enables a Presentation Manager
Application I+ogram to produce high quality text and graphics output to a variety
of output devices. These include both displays and printers and a number of
`special purpose' virtual output devices such as bitmaps and MetaFiles. Output
can, in fact, be directed at any of the following:
• A window on a display screen.
• A printer or plotter device.
• A memory bitmap (i.e., a memory pixel aITay).
• A memory MetaFile (for recording a picture for interchange).
• An information only context useful for querying device information
without incurring all of the memory overheads associated with dis-
playing output.
• Any other device or virtual device for which a I}resentation Driver
(i.e., Hesentation Manager Device Driver) exists.

GPI GRAPHICS SUBSYSTEM STRUCTURE

The GPI graphics subsystem is illustrated in Figure 1-1 and consists of a hierar-
chy of layers below the application. These are the GPI layer, the Graphics Engine,
the Hesentation Driver, and, in the case of certain devices such as printers, the
appropriate Osve Kernel Device Driver. Current Display Presentation Drivers
communicate directly with the display adapter, whereas FTinter I+esentation
Drivers convert the low level graphics calls presented at their Device Driver

1
2 0S/2 PRESENTATION MANAGER GPI

APPLICATION as, I 2.
REREL
I)EVICE
I)RIVER
(NON
DISPLAY
I)EVIC.r:S
ONLY)

Figure 1.1 Graphics Subsystem.

Interface (DDI) into raw printer data, and pass this to the OSA Kernel Pr.int
Device Driver.
Data ownership is also encapsulated within the different layers. The GPI layer
owns the I+esentation Space (PS), the Graphics Engine owns the Device Context
(DC), and the ELesentation Driver owns an extension of the Device Contezit called
the Device Drawing Context (DDC).
Although Figure 1-1 correctly illustrates GPI graphics output for displays and
directly attached printers, the situation when printing via the spooler is rather
more complex (see chapter 12).

PRESEHTATIOH SPACES AHD DEVICE CONTEXTS

GPI function calls are targeted at a FTesentation Space (PS) associated (i.e.,
linked) with a Device Contezat (DC). The DC identifies both the target output
device and the instance of that device (such as a printer or display window) to
which the output is directed. The DC stores such items as the current drawing
attribute values (color, mix, line style, etc.). Memory MetaFiles and Bitmaps also
receive output via DCs of the appropriate type associated with the target PS.
The PS stores presentation space environment attributes and resources. Its
purpose is to retain this information between application calls and across associ-
ations and disassociations of the PS with different DCs. PS data is normally, but
not exclusively, device independent and a PS may also optionally retain (i.e., store)
the entire picture.
For the majority of applications that require only a subset of the GPI functions, a
special PS called a Micro-PS should be used. This has a smaller memory overhead
than a Normal-PS. Also, where large numbers windows each require a PS and DC
for a short sequence of operations, a variation of the Micro-PS called a cached
Micro-PS may be used to allow a PS and DC to be shared between different windows.
(see chapter 2 for a detailed description of device contexts and presentation spaces.)
INTRODUCTION: SIMPLE TEXT AND GRAPHICS OUTPUT 3

OUTPUT TO A DISPLAY WINDOW AND PRINTER

Output of a simple tezit string (say) to a display window requires the following
steps:
1. Obtain a Dc forthe window.
2. Create a ps and associatethe ps andDC.
3. Drawthe text stringto the ps.
4. Destroy the ps if no longer required.
This is illustrated by the function OutputTowindow in Figure 1-2. Note that
WinopenwindowDC can be used only once to open the window DC which then
remains open until the window is destroyed. Thereafter the DC handle can be
obtained using WinQuerywindowDC. Note also that a DC can be associated only
with a single PS, and Gpicreateps (with the GPI_ASSOC option) will therefore
fail if the window DC is already associated.
Performing an equivalent operation for a printer (or plotter) requires the
following steps:
1. Query the printer DRIVDATA (driver data).
2. Open a Device context (DC) for the printer.
3. Create a ps and associatethe ps and DC.
4. Issue a `Start Document' escape to the device.
5. Draw the text stringto the ps.
6. Issue an `End Document' escape to the device.
7. Destroy the ps if no longer required.
8. Close the I+inter DC if no longer required. Note that a printer DC
(unlike a window DC) can be destroyed.
This is illustrated by the function OutputTonrinter in Figure 1-3. The Out-
putTowindow function in Figure 1-2 could have been implemented in a variety of
different ways. A PS type of GPIT_MICRO was, in fact, used to create a Micro-PS,
whereas a Normal or cached Micro-PS could have been used instead.
A number of different character string functions are also available. The function
used, GpicharstringAt, draws a character string starting from a specified posi-
tion. The GPI maintains a current drawing position attribute intemally that is
updated by most GPI output operations (including Gpichar.StringAt). This attri-
bute can also be set directly from an application using Gpisetcurrentposition or
GpiMove. Many GPI functions, including Gpicharstring, draw from (and update)
the current position. The function GpicharstringAt is therefore equivalent to:
Gpisetcurrentposition; and
Gpicharstring.
These two functions could therefore have been used in place of the single
GpicharstringAt function. Note that in the function OutputTowindow, PU ARBI-
TRARY page units are specified together with a default PS page size ;f zero.
PU_ARBITRARY page units cause the specified PS page to be scaled to fit the
4 0S/2 PRESENTATION MANAGER Gpl

available device output area while preserving the aspect ratio (such that a circle
remains a circle). In the case of a display window, the available device output area
is assumed to be constant and equal to the screen size. Either or both PS page
dimensions may be defaulted by specifying as zero, in which case they are
determined by the dimensions of the device output area Out note that for a printer
this is NOT the same as the cu]nent fo]rm. size).
Otherpageunitsarealsoavailable.Anapplicationwishingtodrawindeviceunits
should specify page units of PU_PELS whereas PU_TWIPS, PU_LOENGLISH,
PU_HIENGLISH, PU_LOMETRIC, and PU_HIMETRIC are available for drawing
objectsofspecifiedsizeinmillimetersorinches.TheoutputTonrinterfunctionuses
PS page units of PU_LOMETRIC (i.e., 0.1Inm) and the PS page size is selected to
match the 8.5xll inch printer form. PU_LOMETRIC page units were chosen be-
causetheformsizeinform.ationreturmedbyDevQueryHardcopycaps(usedlater)is
in millimeters. The precise PS page size values are generally unimportant for page
units other than PU_ARBITRARY Out very small values should be avoided).
Chapter 12 describes how the queue name ®szQueue), printer name ®sznrin-
ter), driver name ®szDriver), and device name ®szDevice) used by OutputTol}rin-
ter can be queried from the INI file. For the moment, however, hardcoded string
constants (e.g., "LASER1" or "LPI`1Q") copied from the nrint Manager dialogs will
suffice. Note that some printer drivers (e.g., IBM4019) support only a single device
and require a NULL device name, whereas others (e.g., LASERJET.HPTM
LaseruetTMplus) have a dot qualified extension that must be specified as the device
name.

OUTPUTTIMG A TEXT FILE

Consider now the requirement to output a telit file first to a display window and
then to a printer. Assume the text file has already been read into a memory buffer
(e.g. , using DosAllocate-Dosopen-DosRead-Dosclose).
Clearly, the entire contents of the buffer are unlikely to fit on the display screen
simultaneously and scrolling must therefore be provided. The function Dis-
playTextBuffer in Figure 14 illustrates how this may be accomplished (this
function can, in fact, be substituted for GpicharstringAt in the OutputTowindow
function described earlier).
DisplayTextBuffer begins by erasing the window and resetting the default view
matrix before querying the font metrics. The font metrics provide the character
width and height values needed to convert the row and column scroll offsets into
world (i.e., drawing) coordinates. WinQuerywindowRect is used to determine the
top window coordinate (in pels) and Gpiconvert converts this to world coordinates.
The function GpisetDefaultviewMatrix is used to provide the translation required
by the (lRow, lcol) scroll parameters and GpicharstringAt is used to draw each
row of text. Output begins at the start of the text, works downward, and termi-
mates when the bottom of the window is reached.
The requirements of a function that outputs text to a printer are slightly
different from those of one that outputs to a display. Clearly, the printer is unable
INTRODualoN: slMPLE TEXT AND GRAPHlcs ouTpuT 5

to support scrolling and, instead, the complete document must be printed on


multiple pages with page ejects at the page boundaries and suitable margins on
each page. The function I}rintTextBuffer in Figure 1-5 illustrates how this may be
accomplished (this function can in fact be substituted for GpicharstringAt in the
OutputTOHrinter function described earlier).
FTintTextBuffer is, in fact, quite similar to DisplayTextBuffer with scrolling
removed. DevQueryHardcopycaps is used to determine the fo]rm (or paper) dimen-
sions in millimeters and these are multiplied by ten to convert them to
PU_LOMETRIC page units of 0.1 mm. GpisetGraphicsField is used to provide the
clipping required by the right margin (the other margins are obtained by the
positioning of the text). Each time the bottom of the page is reached,
DevEscapeDEVESC_NEWFRAME is used to perfo]rm. a page eject. Note that
HintTextBuffer requires that the DEVESC STARTDOc and DEVESC ENDDOC
DevEscape functions are issued by the invo-ker.

SIMPLE GRAPHICS OUTPUT

Graphics differ from text in that they use a bottom left origin, whereas text
normally uses top left as illustrated above.

Drawing Primitives and Attributes


Graphics drawing is accomplished using drawing primitive functions (e.g., GpiL-
ine, GpicharstringAt) and drawing attribute setting functions (e.g., Gpisetcolor
GpisetMix). The drawing primitives specify the output operation to be performed
and the drawing attribute functions control the drawing attributes (e.g., color, mix)
of the subsequent drawing primitives. As mentioned earlier, many drawing prim-
itives start at, and update, the current drawing position for the PS, while others
specify their own starting position. The drawing primitives and attributes can be
divided into five groups as follows:
• Characters and Text.
• Lines and Curves.
• Filled Areas (or patterns).
• Markers (e.g., points on a graph).
• Image and BitBlt pixel operations.
Area functions are used for drawing closed figures with a defined shape that are
filled using a specified fill pattern. Markers are typically used to draw the points
on a graph and BitBlt functions are used to transfer rectangular pixel images
between memory bitmaps and raster devices. Image functions are similar to BitBlt
but transfer images from application memory
Some drawing primitive operations combine drawing primitives andyor attri-
butes from more than one group. An example is GpiFullArc which draws a circle
or ellipse, optionally filled with an area fill pattern. Another example is GpiBitBlt
which can combine both Image and Area att,ributes to construct the target image.
6 0S/2 PRESENTATION MANAGER GPI

Each primitive group has its own attribute bundle (or structure) containing the
attributes for that particular primitive type. Instances of color and mix attributes
appear in all attribute bundles and are known as `global attributes.' Other bundle
attributes appear in only a single bundle. Exalnples of the latter are the area fill
pattern and character direction. Other general attributes apply to all primitives
and are not part of any attribute bundle. Exalnples of these are the Current
Position, Model Thansform, and Viewing (clip) Limits.
As mentioned above, the appearance (color, size, etc.) of GPI graphics output is
controlled by the bundle attributes for the primitive type concerned, which may be
set to the required values before drawing. For characters, the CIIARBUNDIE
(character bundle) is used; for lines, the LINEBUNDLE (line bundle) is used; for
areas, the AREABUNDLE (area bundle) is used; for markers, the MARKERBUN-
DLE (marker bundle) is used; and for BitBlt and image, the IMAGEBUNDLE
(image bundle) is used. It is not essential to set the bundle attributes before
drawing as the default value can be used for most bundle attributes ®undle
attributes are reset to default by GpiResetps). Note, however, that for most
devices, the default character set is a raster font and several of the CIIARBUNDLE
attributes are ignored for character mode CM MODE 1 raster characters. For those
devices that provide an outline font as the -default, the character box attribute
(height and width) must be set to the required character box size in world coordi-
mates to ensure that correctly sized characters are obtained. Character angle,
direction, and shear attributes can be defaulted for both outline and raster fonts.
The functions DrawText, DrawLines, DrawArea, DrawMarkers, and WCBitBlt
in Figures lno to 1-10 set each of the appropriate bundle attributes before
performing the text, line, area, marker or BitBlt output operation. Note that in the
case of DrawLines, certain of the LINEBUNDLE attributes that apply exclusively
to paths are not referenced by this function. These are discussed in chapter 3. In
the WCBitBlt example, the bitmap used would typically have been created using
the icon editor and included in the .rc file using a statement of the form:

BITMAP ID_BITMAP3 mybmap.bmp

where ID_BITMAP3 is a numeric constant (e.g., #define ID_BITMAP3 3) specified


as the WCBitBlt (and GpiLoadBitmap) usBitmapld parameter.

Simple Transformations
The GPI transform functions enable rotation, scaling, and translation of subse-
quent output to be controlled by a transformi matrix attribute.
There are a number of different transforms to choose from but in general, the
model transform can be varied during drawing for the purpose of picture construc-
tion (i.e., picture modeling) and the default viewing transformi should be used for
scaling and scrolling and remain constant for the complete picture. The examples
in this section use the model transfo]rm. but apply equally to the default viewing
transform (although rotations other than 90 degrees would not normally be
applied to the whole picture).
INTRODUCTION: SIMPLE TEXT AND GRAPHICS OUTPUT I

The function Rotate in Figure 1-11 illustrates how a figure can be rotated about
a given point in the figure (note that rotation about the origin would produce an
additional undesired translation). The function Scale in Figure 1-12 illustrates
how a figure can be scaled relative to a given point in the figure (note that scaling
relative to the origin would produce an additional undesired translation). The
function Thanslate in Figure 1-13 illustrates how a figure can be translated by a
specified amount.
The `transformi helper functions,' GpiRotate, Gpiscale, and GpiThanslate, sim-
plify transformi construction but are not absolutely essential. It is possible to
calculate the correct matrix values and obtain the required result by a sequence
of set transfo]rm matrix operations (see chapter 7).

RULES AHD CONCEPTS

The GPI Graiph[cs Model: Picture and Envfronment/Resources

The GPI model views the graphics functions as belonging to one of two groups:
• Picture Functions; or
• PS Environment and Resource Functions.
Picture Functions are drawing primitive functions (such as line, arc, character
string) and drawing attribute setting functions (such as set color, set mix) used to
construct the picture and vary the drawing attributes as the picture is drawn. Any
function that can cause a graphics order to be built and stored in a retained
graphics segment (see chapter 9) can be regarded as a picture function. In addition,
there are a small number of picture functions for non-retained use only that do not
add an order to a retained segment. These are:
GpiBitBlt;
Gpipaintkegion;
Gpisetpel; and
WinDraw functions (e.g. , WinDrawText).
Except for the default attribute functions (which are envirormient attributes),
picture functions are those functions described in chapter 3. All other functions are
Environment and Resource Functions (or neither).
Environment and Resource Functions are functions that create and load re-
sources (such as logical fonts and color tables) or functions that establish environ-
ment attributes (such as graphics field and default viewing transform). These
shouldgenerallybeestablishedbeforethepictureisdrawnandremainunchanged
during drawing (although it is permissible to incrementally create and load
additional resources as they are needed). Of course it is quite possible for an
application to vary the resources and environment attributes during picture
construction. However, apart from this being unnecessary because of the rich set
of picture functions available, there are other good reasons for not doing so. It is
8 0S/2 PRESENTATION MANAGER GPI

extremely useful to have functions such as Graphics Field and Default Viewing
Thansfo]rm available exclusively for defining rectangular clipping and scaling for
the complete picture. Also, if the picture is to be recorded in a MetaFile for
interchange, an SAA conforming MetaFile will not be produced if environlnent
attributes or resources are modified during picture constmction. Such a MetaFile
will not properly conformi to the interchange architecture and, although it will
normally interchange successfully with other OSA nresentation Manager sys-
tens, picture information will be lost, or errors will occur, if interchange is
attempted with other products that support this architecture.

Reta[ned and Hen-Reta[ned Graph]cs


An application that chooses to store its graphics picture in application memory and
issue every GPI function call required for picture reconstruction each time a
repaint is required is called a non-retained application.
As mentioned earlier, it is also possible for a PS to store the entire graphics
picture. The same GPI functions are used for retained picture construction but
with the PS in `Retain' mode, such that GPI picture functions are accumulated as
drawing orders in PS segment store rather than being displayed and discarded.
These drawing orders are grouped together in objects known as graphics seg-
ments. An entire retained graphics picture can then be repainted from retained
graphics segment store by a single GpiDrawchain call.
Retained graphics would be useful for a picture transmitted for remote display
in a network, or for any local application requiring this type of picture storage
capability. Also, when the PS stores the entire picture, it is very simple to
disassociate the PS from a window DC and reassociate it with a different DC,
making it easy to print the picture or to record it in a MetaFile.
Retained graphics segments can be called from other retained segments or
drawn by a non-retained application using the GpiDrawsegment and
GpicallsegmentMatrix functions. It is possible to use a mixture of non-retained
and retained graphics, with a non-retained application drawing retained segments
for those picture objects that are drawn multiple times with different positions and
sizes.
It is also possible to edit existing retained segments. Functions exist to enable
retained segments to be reopened and elements (i.e., groups of one or more
drawing orders) to be inserted and deleted as required.

Correlation and Boundary Aceumulation


In addition to providing the ability to draw graphics to a variety of output devices
or DC types, the GPI provides functions that return information about a picture
to the application.
Boundary Accumulation is useful for determining the smallest bounding rectan-
gle into which the entire picture will fit. This can be regarded as the `high water
mark' of the picture coordinates and is useful for scaling the picture to fit an output
rectangle (see for example, the function SubpictureMetaFile in chapter 11) and for
INTRODUCTION: SIMPLE TEXT AND GRAPHICS OUTPUT 9

performingoptimizations.Forexample,ifpardofthewindowneedstoberepainted
and the area to be repainted does not intersect the bounding rectangle then no
drawing (other than an erase) need occur. The picture boundary data can also be
used to predict whether a particular transfo]rm operation will result in coordinate
overflow (see chapter 7).
ColTelation is provided for interactive graphics. A frequent end-user operation
is that of selecting an object on a display screen by pointing using a mouse and
screen pointer or cursor. The object might then, for example, be dragged to a
different position, changed to a different color or deleted by the user. To identify
the object, the application must determine which primitive or primitive group from
the picture corresponds to the screen coordinates of this selection.
Correlation assists this operation by establishing a movable correlation rectan-
gle (which an application would typically move with the pointer) and identifying
to the application which drawing primitives or retained graphics segments inter-
sect this rectangle. This correlation rectangle is known as the pick aperture.

Coordinates

GPI Coordinate Limits

Many GPI functions have one or more coordinate pairs as a parameter. In most
cases the coordinates are defined in a space known as world coordinate space, but
some functions require their coordinates to be specified in an intermediate space
above the device (e.g., the PS page) whereas others are specified directly in device
coordinates. World coordinates, as they are called, and other intermediate coordi-
nates are transformed by the various GPI transforms down to the device, produc-
ing output in device coordinates. These non-device coordinates are specified as 32
bit integers that must be in the (28 bit) range OxF8000000J)x07FFFFFF (i.e.,
-134217728 to 134217727). Furthermore, when transformed to device space, the
resultant device coordinates must be in the (16 bit) range OxFFFF8000-
Ox00007FFF (-32768 to 32767). This 16 bit restriction also applies to device
coordinates that are specified directly. These restrictions are necessary to avoid
coordinate overflow.

Retained Segment and MetaFile Coordinate Limits

When GPI drawing primitives are used to construct a retained graphics picture or
recorded in a MetaFile, graphics drawing orders containing primitive coordinates
are built and accumulated in graphics segments. Depending on the coordinate
format option specified with Gpicreateps, drawing order coordinates are either
stored in long (4 byte) format which is the default, or short (2 byte) format.
Coordinates stored in short format require less memory for retained picture and
MetaFile storage but it is the responsibility of the application to ensure that
truncation of 32 bit primitive coordinates to 16 bit order coordinates does not result
inlossofdata(alargepositivevaluegreaterthan32767couldappearnegativeafter
truncation). For performance reasons, no checking is performed by the system.
10 0S/2 PRESENTATION MANAGER GPI

Rectangle Boundaries

Many GPI functions require a rectangle (i.e., two pairs of coordinates) as a


parameter. Examples are the box primitive and clip region functions. There is a
fairly simple rule to determine which rectangle boundaries are inclusive (i.e., part
of the rectangle interior), and which are exclusive (i.e., outside the rectangle). If
defined in device coordinates, rectangle coordinates are inclusive at the bottom
and left boundaries and exclusive at the top and right boundaries. When two
boundaries are the same, the rectangle is null. If defined in any coordinate space
other than device space, rectangle coordinates are inclusive at all boundaries.

Staying Respons]ve and Mult]-threaded Applications


In an environment such as Ospe that supports multiple applications, it is import-
ant that all applications are well-behaved and remain responsive to the end user.
This is ensured if applications always complete their message queue processing
and return to process the nelit message from the queue in less than 0.5 seconds.
Graphics output in particular, including drawing to a queued printer DC, can take
a considerable time to complete, and all but very simple drawing operations should
therefore be performed on a separate asynchronous thread.
Although most GPI applications are likely to be multi-threaded, the same GPI
PS may not be used re-entrantly on different threads (i.e., by issuing simultaneous
GPI function calls). If this is attempted, a GPI error OMERR_PS_BUSY) may
occur. The one exception to this is the GpistopDraw function which can be used to
stop the drawing operation being performed on a different thread. Typically, this
is used to modify the operation as a result of a new message received from the
message queue. See chapter 9 for a description of GpistopDraw.

FIXED Numbers

A number of GPI functions have parameters of type FIXED. Examples are char-
acter box attribute and transfo]rm matrix elements in the earlier examples. FIXED
numbers are signed 4 byte numbers with a notional decimal point between the
middle two bytes. This representation can be viewed as the original number
multiplied by 65.536. For example:
2.5 is Ox00028000;

2.0 is Ox00020000;

1.0 is OxOOO10000;

0.5 is OxOOOO8000;

0.25 is Ox00004000;

0.125 is Ox00002000;

etc.
INTRODUCTION: SIMPLE TEXT AND GRAPHICS OUTPUT 11

FIXED numbers obey all the normal rules of binary arithmetic and negative values
aresimplythetwoscomplementofthecorTespondingpositivenumber.Forexample:

2.25 is Ox00024000; and


-2.25 is OxFFFDC000.

A MAKEFIXED macro is available to assist fixed number construction.

Error Handling

In the interest of simplicity, no eITor checking is included in the examples provided


in this chapter, although full error checking is included in the examples through-
out the remaining chapters of this book.
Ideally, all applications should check all return codes from Base OSA and
Hesentation Manager function calls. It is, however, an application designer's
choice as to how much error checking should be included, and there is a case for
omitting this checking for simple functions (e.g., simple drawing attribute and
primitive functions as Gpisetcolor and GpiLine). Error checking is particularly
important during application development and testing. It is recommended as an
absolute minimum, that all returned handles, and all return values from functions
that create, load, and delete ob].ects or resources, should always be examined for
error. The memory and performance overhead incurred error checking is likely to
be small, particularly if the return codes can be held in registers.
Whereas Base OS/2 calls (e.g., DosAllocseg) return a zero for ok or a non-zero
error number, FTesentation Manager functions generally return NULL or zero
(GPI_ERROR) for error and a non-zero function value for ok. Where zero repre-
sents a valid return value, an alternative value such as minus one (GPI AL-
TERROR) or -255 (CLR_ERROR) is used to indicate an error. Many GPI functions
(e.g., Gp.isetcolor) return a BOOL:
TRUE (1) - ok; and
FALSE (0) - error.
Note that the symbol TRUE should only be used with extreme caution by an
application as TRUE is defined as ONE, and does not have the same meaning as
true in the C language which means any non-zero value.
The GPI drawing primitives (e.g., GpiLine) return a `LONG' having one of three
values:
GPI ERROR (0) -error;
GPI OK (1) -ok; and
GPI HITS (2) -a correlate hit occurred.
If correlation is not enabled, a code simplification may be achieved by casting
this `LONG' to a `BOOL' (this technique is used by a number of examples in this
book).
12 OS/2 PRESENTATION MANAGER GPI

If a Hesentation Manager function returns elTor, an error code providing more


information about the error is logged intemally and can be retrieved together with
a severity value using WinGetlastError.
PM Error codes are defined in PMERR.H and base OSA error codes in
BSEERR.H. Severities are defined in PMWIN.H as one of the following:
SEVERITY NOERROR 0xcOOO;
SEVERITY WARNING 0xcO04;
SEVERITY ERROR 0xcOO8;
SEVERITY SEVERE 0xcOOC; and
SEVERITY UNRECOVERABLE 0xOO10.
The macros ERRORIDERROR and ERRORIDSEV are useful for extracting
the error code and severity from the ERRORID value returned by
WinGetLastError.
Logged errors of severity SEVERITY_WARNING indicate a minor error that the
system was able to correct. No error is returned by the function concermed and
such `warnings' are therefore only visible to an application if a function such as
WinGetLastError is issued in the absence of an error return code. Warnings are,
in fact, sometimes logged intemally by the system during normal operation and
are no cause for concern.
Errors of severity SEVERITY_ERROR and higher are more serious and cause
the function concerned to give a return code of error.
WinGetErrorlnfo can be used to obtain yet more information about a logged
error. Like WinGetLastError, this too provides the error code and severity and also
provides a null terminated text string describing the error. In addition, if the
logged error was PMERR_BASE_ERROR then the error occurred in an underlying
Base OSA call that resulted from processing the original request. In this case, the
Base OS/2 error number is also provided by WinGetErrorlnfo. Note that
WinGetErrorlnfo should always be followed by WinFreeErrorlnfo to release the
memory.
Use of WinGetErrorlnfo is illustrated by the function DisplaypMError in Figure
1-14. This can be used when an error is returned by any Presentation Manager
function call. It displays a message box containing:
Hexadecimal PM error code;
Hexadecimal Severity value;
Decimal Base OS/2 Error number (if PM error is
PMERR_BASE_ERROR); and
PM Error Message string.
For retained graphics drawing functions, correlation functions, and functions that
process an order buffer (i.e., GpiputData and GpiElement), an additional function
is provided for obtaining error information:
INTRODualoN: slMPLE TEXT AND GRAPHlcs ouTpuT 13

GpiErrorsegmentData
For retained segment functions, this returns the segment name and element
number at which the error occurred. For GpiputData or GpiElement, it returns
the byte offset into the buffer at which the error occurred.

optowi.nd.c */
OutputTowi.ndow(HWND hwnd)

Obtal.n a Devi.ce Context (DC) for the wl.ndow.


Create a Gpi. Presentati.on Space (PS) and associ.ate the PS and DC.
Draw the text stri.ng to the PS.
Destroy the PS.

1.nputs: hwnd wl.ndow handle

"Gpi. W1.ndow text"


#defi.ne GPIWTEXT
#define NGPIWTEXT ( LONG ) ( s I. zeof ( GP I WTEXT ) -1 )

HDC hdc /* dl.splay wl.ndow DC handle */


HPS hps /* PS handle */
SIZEL sl.zlpspage /* PS page sl.ze */
P0INTL ptlposn /* drawl.ng posi.tl.on */

I :***************************************************************************** I
/**/
/* Obtai.n a Devi.ce Context (DC) for the wl.ndow. */
/**/
/******************************************************************************-/

/* query Wl.ndow DC
hdc = W1.nQueryw1.ndowDC(hwnd); /* -wl.ndow handle
I.f (hdc == NULL) /* open wi.ndow DC I.f NULL
hdc = Wl.nopenwl.ndowDC(hwnd) /* -wi.ndow handle

/ :.***************************************************************************** I

(: CreateaGpi presentatlonspace(PS)andassociatethepsandDC :)
1******************************************************************************-I

i;!Z];i;:::::; = §[; ): ::: ::e:::eG§:!m::S1.Ons


hps = Gpi.Createps( Wl.nQueryAnchorBlock(hwnd) /* -anchor block handle
hdc /* -DC handle
& s 1. z 1 P S P a g e /* -PS page sl.ze
P U_A RB I T RA RY /* -Optl'ons
G P I F_D E FAU LT
G P I T_M I C R0
G P I A_A S S 0 C

Figure 1.2 0utputTowindow Function


14 OS/2 PRESENTATION MANAGER GPI

/ ****************************************************************************** /
/**/
/* Draw the text stri.ng to the PS. */
/**/
/ ****************************************************************************** 1

ptlposn.x -200; /* set drawl.ng posi.ti.on


ptlposn.y -200: /* draw character strl.ng
Gpi.Charstri.ngAt( hps /* -PS handle
&ptlposn /* -starti.ng posi.ti.on
NGPIWTEXT /* -number of characters
GPIWTEXT /* -character strl.ng
in

/ ****************************************************************************** 1
/**/
/* Destroy the PS. */
/**/
/ ****************************************************************************** /

/* destroy the PS
Gpi.Destroyps( hps ); /* -PS handle

return ;

Figure 1.2 (co7?££7}ttec!)

/* Optoprtr.c */
VOID 0utputToprl.nter(

/* Query the printer dri.ver data.


/* Open a Devi.ce Context (DC) for the prl.nter.
/* Create a Gpl. Presentatl.on Space (PS) and assocl.ate the PS and DC.
/* Issue a 'Start Document' escape to the pri.nter.
/* Draw the text strl.ng to the PS.
/* Issue an 'End Document' escape to the prl.nter.
/* Destroy the PS.
/* Close the Pri.nter DC.
/*
/* l.nputs: hab anchor block handle
/* pszQueue Queue name e.g. "LPT10")
/* pszpri.nter Prl.nter name e.g. "PRINTER1"
/* pszDrl.ver Drl.ver name e.g. "LASERJET" or "IBM4019
/* pszDevl.ce Devi.ce name e.g. "HP Laserjet 11"
/* (or NULL for IBM4019)
/*

Figure 1.3 0utputTonrinter Function.


INTRODUCTION: SIMPLE TEXT AND CRAPHICS OUTPUT 15

I,*,*****************************************************************************/
/* */

): ::g:u=i§fi!TR:: ::;!g:tofe8::S:a: form sl.Ze of letter (8.5 x 11 I.nches) :)


/* */
1******************************************************************************'1

#defi.ne PSPAGEWIDTHP 2159L


#defi.ne PSPAGEHEIGHTP 2794L

"Prl.nt Job„
#defi.ne PDOCNAME
#defi.ne PDOCNAMELEN ( LONG ) s i zeof ( PDOCNAM E )
"Gpi Prl.nt Text'.
#defi.ne GPIPTEXT
#defi.ne NGPIPTEXT ( LONG ) ( s 1. zeof ( GP I PTEXT ) -1 )

PDRIVDATA p d r i. v D a t a /* poi.nter to DRIVDATA


DEVOPENSTRUC dopData /* DEVOPENSTRUC structure
SIZEL si zl pspage /* PS page sl.ze
P0INTL ptl Posn /* drawl.ng posl.ti.on
LONG 1 Length /* length
USHORT usJobld /* job l'd
HDC hdc /* DC handle
HPS hps /* PS handle

I,:.:**+**********************+*************************************+************1
/* */
/i Query the prl.nter drl.ver data. */
/* */
/***************+**************************************************************I/

lLength = DevpostDevi.ceModes( hab )= 9:::%o:R:I::lAh:::i:h

: #rl.ver ;: :3::#:TAa::l.nter
pszDevl.ce /* -devl.ce name
pszprinter /* -pri.nter name
DPDM_QUERYJ0BPROP /* -opti.ons
in

pdri.vData = malloc((SHORT)1Length); /* allocate DRIVDATA memory

/* query DRIVDATA
DevpostDevl.ceModes( hab /* -anchor block handle
pdri.vData /* -DRIVDATA poi.nter
pszDri.ver /* -dri.ver name
pszDevi.ce /* -devi.ce name
pszpri.nter /* -pri.nter name
DPDM_QUERYJ0BPROP /* -Optl.ons
):

/,*f****************************************************************************/
/L
/* */
/: Open a Devi.ce context (DC) for the prl.nter. */
/* *//
/******************************************************************************'/

Figure 1.3 (co7i££7?zteczJ


16 OS/2 PRESENTATION MANAGER GPI

/* set DevopenDC params


/* and open a printer DC
dopData . psz LogAdd ress pszQueue ; /* -logical address
d o p D a t a . p s z D r 1. v e r N a in e p s z D r 1. v e r /* -dri.ver name
d o p D a t a . p d r i. v P d r i. v D a t a : /* -DRIVDATA
I
dopData . pszDataType PM_Q_STD„ /* -data type
``Gpi Print„;
dopData . pszcomment /* -comment
dopData . pszQueueprocName NULL: /* -queue proc name (default)
"COL=C XFM=0";
dopData . pszQueueprocpa rams /* -queue proc params
dopData . pszSpool erparams NULL: /* -spooler params
dopData . pszNetworkparams NULL: /* -network params (not used)
hdc = DevopenDC( hab /* -anchor block handle
OD_QUEUED /* -DC type
I * ,,
/* -token
9L /* -number of data elements
(PDEVOPENDATA)&dopData /* -open DC data
NULL /* -compati.ble DC handle
in

f r e e ( p d r 1. v D a t a ) ; /* free DRIVDATA memory */

/ ****************************************************************************** /
/**/
/* Create a Gpl. Presentatl.on Space (PS) and assocl.ate the PS and DC */
/**/
/ ****************************************************************************** 1

si.zlpspage.cx = PSPAGEWIDTHP: /* set PS page dl.mensl.ons


si.zlpspage.cy = PSPAGEHEIGHTP /* and create Gpl. PS
hps = Gpl.Createps( hab /* -anchor block handle
.hdc /* -DC handle
& s 1' z 1 P S P a 9 e /* -presentatl.on page sl.ze
PU LOMETRIC /* -Optl'Ons
GP I F_D E FAU LT
GPIT MICRO
GPIA-ASSOC

/ ****************************************************************************** 1
/**/
/* Issue a 'Start Document' escape to the pri.nter. */
/**/
1 ****************************************************************************** 1

/* start document escape */


DevEscape( hdc /* -DC handle */
DEVESC_STARTDOC /* -escape code */
PDOCNAMELEN /* -si.ze of document name */
PDOCNAME /* -null termi.nated doc name */
NULL /* -sl.ze of op data (not used)*/
NULL /* -output data (not used) */
in

/ ****************************************************************************** /
/**/
/* Draw the text strl.ng to the PS. */
/**/
/ ****************************************************************************** 1

Figure 1.3 (co7i££nL4ecz)


INTRODUCTION: SIMPLE TEXT AND GRAPHICS OUTPUT 17

ptlposn.x -1000; /* set drawl.ng posi.ti.on


ptlposn.y -1000; /* draw character strl.ng
Gpi.Charstri.ngAt( hps /* -PS handle
&ptlposn /* -starti.ng posi.ti.on
NGPIPTEXT /* -number of characters
GPIPTEXT /* -character strl.ng
in

/:_:***************************************+************************************1
/* */
/* Issue a .End Document. escape to the prl.nter. */
/* */
/******************************************************************************'1

1Length = 2L: /* end document escape


DevEscape( hdc /* -DC handle
DEVESC_ENDDOC /* -escape code
OL /* -length of 1.nput data (OL)
NULL /* -i.nput data (not used)
. &1Length /* -sl.ze of output data (2L)
(PBYTE)&usJobld /* -returned job 1.d
);

/,*.***********************************************************************k*****1
/*
I

*/
/? Destroy the ps. */
/* */
1*********************************************+********************************'1

Gpl.Destroyps( hps ); ;: 9;§t::%d::e ps :;

/,*+****************************************************************************/
rl IIT
/* */
/I Destroy the DC. */
/* */
/****************************************************************+*************'1

/* Close the DC
DevcloseDC( hdc ); /* -DC handle

return ;

Figure 1.3 (co7?££7}z/ecg)


18 OS/2 PRESENTATION MANAGER GPI

dl.sptext.c */
D Di.splayTextBuffer(HPS hps, HWND hwnd, PCH pchData, LONG IRow, LONG ICol)

Di.splay a buffer of text, typl.cally read from a text fi.1e, i.n the
speci.fi.ed wi.ndow (vi.a the speci.fi.ed PS) usl.ng the current font.

The followi.ng assumpti.ons are made:

1. The speci.fi.ed PS 1.s associ.ated wi.th a DC for the speci.fied wi.ndow

2. The text contal.ns no null characters, each row 1.s termi.nated by


carrl.age return (OxOD) and ll.ne feed characters (OxOA) and the
fi.nal row i.s termi.nated by end-of-fi.le (OxlA).

PS handle
wi.ndow handle
row ori.gi.n (scrolli.ng offset)
colum orl.gi.n (scrolli.ng offset)
poi.nter to text buffer

LONG ICount /* character count


P0INTL ptlposn /* coordi.nate posl.tl.on
FONTMETRICS fmMetri.cs /* FONTMETRICS structure
PCH pchRow /* pointer to start of row
PCH pchRowEnd /* poi.nter to end of row
RECTL rclwi.nd /* wi.ndow rectangle
stati.c MATRIXLF matlfDV /* default vi.ew matri.x
{ Oxl0000, OL, OL, OL, Oxl0000, OL, OL, OL,1L )

I ****************************************************************************** I
/**/
/* Erase the wi.ndow and reset the default vi.ew matrl.x. */
/**/
1 ****************************************************************************** I

G p i. E r a s e ( h p s ) : /* -PS handle */

matlfDV.IM31 = OL;
matlfDV.IM32 = OL;
Gpi.SetDefaultvi.ewMatri.x( hps /* -PS handle */
9L /* -count of matri.x elements */
&matlfDV /* -transform matri.x */
TRANSFORM_REPLACE /* -opti.ons */
in

/ ****************************************************************************** /
/**/
/* Query the metrl.cs of the current font. */
/**/
1 ****************************************************************************** I

Gpl.QueryFontMetrl.cs( hps /* -PS handle


(LONG)sl.zeof(FONTMETRICS) /* -length of metrl.cs
&fmMetri.cs /* -returned metri.cs
);

Figure 1.4 DisplayTextBuffer Function.


INTRODUCTION: SIMPLE TEXT AND GRAPHICS OUTPUT 19

/ ****************************************************************************** 1
/**/
/* Query the wi.ndow coordl.nates 1.n pels and use thi.s to determi.ne the */
/* maxi.mum wi.ndow y coordi.nate i.n world coordi.nates. */
/* Ini.ti.all.ze the x and y starti.ng coordi.nates to top left of the wi.ndow */
/* and the row poi.nter to the buffer start. */
/**/
1****************************************************************************** I

Wl.nQuerywl.ndowRect( hwnd /* -wi.ndow handle


&rclwi.nd /* -wi.ndow rectangle
in
ptlposn.x = OL;
ptlposn.y = rclwi.nd.yTop;
Gpi.Convert( hps /* -PS handle
CVTC_DEVICE /* -source
CVTC_WORLD /* -target
1L /* -number of coordl.nates
&ptlposn /* -coordi.nate array
);

ptlposn.x = OL:
ptlposn.y -= fmMetrl.cs.1MaxAscender;
pchRow = pchData:

1 ****************************************************************************** I
/**/
/* Set the Default Vi.ew Matri.x translatl.on to provi.de the speci.fi.ed */
/* (row, column) scroll offsets. */
/**/
I ****************************************************************************** I

matlfDV.1M31 = -1Col * fmMetrl.cs.1Avecharw1.dth:


matlfDV.IM32 = lRow * (fmMetrl.cs.IMaxBasell.neExt+fmMetrl.cs.1ExternalLeadl.ng):
Gpi.SetDefaultvl.ewMatrix( hps /* -PS handle */
9L /* -count of matrl.x elements */
&matlfDV /* -transform matri.x */
TRANSFORM_REPLACE /* -opti.ons */
in

/ ****************************************************************************** 1
/**/
/* Locate newll.ne, carri.age return or end of fl.le to fi.nd end of fl.rst row. */
/**/
/ ****************************************************************************** I

pchRowEnd = strpbrk(pchRow, "\n\r\xlA'.):

/ ****************************************************************************** /
/**/
/* Whi.1e end-of-fi.le has not been reached perform the followi.ng: */
/* 1. Draw characters i.n current row. */
/* 2. Process carri.age return and newll.ne at row end. */
/* 3. If bottom of wi.ndow 1.s reached then break (to i.mprove performance). */
/* 4. Locate end of next row. */
/**/
/ ************+***************************************************************** I

Figure 1.4 (co7}££7"ecz)


20 OS/2 PRESENTATION MANAGER GPI

whi.le (*pchRow != OxlA )


(
1Count = pchRowEnd-pchRow
Gpi.Charstri.ngAt( hps /* -PS handle */
&ptlposn /* -starti.ng posi.ti.on */
lcount /* -number of characters */
pchROw /* -character strl.ng */
):

pchRow += 1Count;
whi.1e (*pchRow == .\r. || *pchRow == '\n')
(
l.f (*pchRow == .\r' )
ptlposn.x -OL:
else
ptlposn.y -= (fmMetrl.cs.1MaxBasell.neExt + fmMetrl.cs.1ExternalLeadl.ng);
pchROw++;
)

i. f ( ptl Posn .y -fmMetri. cs .1 MaxDescender+1 Row* ( fmMetri. cs .1 MaxBasel i. neExt


+fmMetrl.cs.IExternalLeadi.ng) < OL)
break;

pchRowEnd = strpbrk( pchRow, "\n\r\xlA.');


)
return :

Figure 1.4 (co7i££nttec!)

pri.ntext.c */
D Prl.ntTextBuffer(HPS hps, PCH pchData)

Output a buffer of text, typl.cally read from a text fi.1e, to the


pri.nter (vl.a the speci.fl.ed PS) usi.ng the current font.

The follwi.ng assumpti.ons are made:

1. The specl.fl.ed PS l.s assocl.ated wi.th a prl.nter DC.

2. The PS Page Unl.ts are PU_LOMETRIC.

3. The text contal.ns no null characters, each row i.s terml.nated by


carri.age return (OxOD) and li.ne feed characters (OxOA) and the
fl.nal row l.s termi.nated by end-of-fl.le (OxlA).

4. .start document' and lend document' escapes are 1.ssued by the caller
before and after i.nvocati.on.

i.nputs: hps Ps handle


pchData pol.nter to text buffer

1 ****************************************************************************** 1
/**/
/* margi.ns are defi.ned 1.n PU_LOMETRIC uni.ts of 0.1 mm */
/**/
/ ****************************************************************************** I

Figure 1.5 I+intTextBuffer Function.


INTRODUCTION: SIMPLE TEXT AND GRAPHICS OUTPUT

#defl.ne TOPMARGIN 120L


#defi.ne B0TTOMMARGIN 200L
#defi.ne LEFTMARGIN 150L
#defi.ne RIGHTMARGIN 100L

HDC hdc DC handle


LONG ICount character count
LONG i NumForms number of forms
LONG i FormHei.ght form hei.ght mm
LONG I Formwi.dth form wi.dth
LONG I FormTopcl i.p form top
LONG I FormBottomcl 1.p form bott
LONG I FormLeftcll.p form left cli.p
P0INTL ptlposn coordl.nate posi.ti.on
PHCINF0 phci.Forms poi.nter to forms array
FONTMETRICS fmMetrl.cs FONTMETRICS structure
PCH pchRow poi.nter to start of row
PCH pchRowEnd poi.nter to end of row
LONG 1 array i.ndex
RECTL rclFi.eld graphi.cs fi.eld

/ ****************************************************************************** /
/**/
/* Query the handle of the associ.ated DC. */
/**/
/ ****************************************************************************** /

hdc = Gpl.QueryDevl.ce(hps); /* -PS handle */

/ ****************************************************************************** 1
/**/
/* Query the metrl.cs of the current font. */
/**/
/ ****************************************************************************** 1

Gpl.QueryFontMetrl.cs( hps /* -PS handle


(LONG)si.zeof(FONTMETRICS) /* -length of metri.cs
&fmMetrl.cs /* -returned metri.cs
);

/****************************************************************************** /
/**/
/* Determi.ne the paper si.ze and cli.p boundari.es of the current form. */
/* 1. Query number of forms. */
/* 2. Allocate Memory. */
/* 3. Query the forms. */
/* 4. Locate the current form. */
/* 5. Convert the forms 1.nformati.on from mm to PU_LOMETRIC uni.ts of 0.1 mm. */
/* 6. Free the memory. */
/**/
/ ****************************************************************************** 1

Figure 1.5 (co7}£Z77t/ecz)


22 OS/2 PRESENTATION MANAGER GPI

INumForms = DevQueryHardcopycaps( hdc /* -DC handle


OL /* -fi.rst form requested
OL /* -number of forms requested
NULL /* -returned HCINF0 forms array
in
phci. Forms = mal 1 oc( (SHORT)l NumForms*si.zeof(HCINFO) ) ;

DevQueryHardcopycaps( hdc /* -DC handle


OL /* -fi.rst form requested
lNumForms /* -number of forms requested
phci.Forms /* -returned HCINF0 forms array
in

for (I.=0: 1.<lNumForms-1 && !(phcl.Forms[i.].flAttrl.butes & HCAPS_CURRENT); i++):

1FormHei.ght = phcl.Forms[i.].cy * 10 ;
lFormwi.dth = phci.Forms[i.].cx * 10 ;
1FormTopclip = phci.Forms[i.].yTopcli.p * 10:
lFormBottomcli.p = phci.Forms[i.].yBottomcli.p * 10 :
lFormLeftcli.p = phcl.Forms[i.].xLeftcli.p * 10 ;

f ree ( phci. Forms ) :

/ ****************************************************************************** /
/**/
/* Set graphi.cs fl.eld to cli.p at ri.ght margi.n. */
/**/
/ ****************************************************************************** 1

rclFi.eld.xLeft = OL:
rclFi.eld.yBottom = OL:
rclFl.eld.yTop = lFormHel.ght;
rclFi.eld.xRight = lFormwi.dth -RIGHTMARGIN
Gpi.SetGraphi.csFi.eld( hps /* -PS handle
&rclField /* -graphi.cs fi.eld
);

1 ****************************************************************************** /
/**/
/* Inl.tl.all.ze drawl.ng posi.ti.on to top left and row pol.nter to buffer start. */
/**/
/ ****************************************************************************** I

ptlposn.y = mi.n(lFormHei.ght-TOPMARGIN, lFormTopCll.p) -fmMetri.cs.IMaxAscender;


ptlposn.x = max(LEFTMARGIN, lFormLeftcli.p);
pchRow = pchData;

/ ****************************************************************************** 1
/**/
/* Locate newli.ne, carri.age return or end of fi.le to fi.nd end of fi.rst row. */
/**/
1 ****************************************************************************** I

Figure 1.5 (co7?f£7?L6ecz)


INTRODUCTION: SIMPLE TEXT AND GRAPHICS OUTPUT 23

pchRowEnd = strpbrk(pchRow, "\n\r\xlA'.):

/ ****************************************************************************** 1
/**/
/* Whi.le end-of-fi.1e has not been reached perform the followi.ng: */
/* 1. Draw characters i.n current row. */
/* 2. Process carri.age return and newll.ne at row end. */
/* 3. If at bottom of page i.ssue 'new frame' escape & reset drawl.ng posi.ti.on.*/
/* 4. Locate end of next row. */
/**/
I ****************************************************************************** 1

whi.le (*pchRow != OxlA )


(
1Count = pchRowEnd-pchRow
Gpi.Charstri.ngAt( hps /* -PS handle */
&ptlposn /* -starti.ng posl.tl.on */
1Count /* -number of characters */
/* -character strl.ng */
pchROw
):

pchRow += lcount;
whi.le (*pchRow == '\r' || *pchRow == '\n')
(
i.f (*pchRow == '\r' )
ptlposn.x = max(LEFTMARGIN,1FormLeftcli.p):
else
ptlposn.y -= (fmMetrl.cs.1MaxBasell.neExt + fmMetrl.cs.1ExternalLeadi.ng);
pchROw++:
)

i.f (ptlposn.y -fmMetri.cs.1MaxDescender < max(B0TTOMMARGIN,1FormBottomcll.p))


(
DevEscape( hdc /* -DC handle
DEVESC_NEWFRAME /* -escape code
OL /* -length of i.nput data (OL)
NULL /* -l.nput data (not used)
NULL /* -si.ze of output data (OL)
. NULL /* -output data (not used)
n
ptlposn.y = mi.n(1FormHei.ght-TOPMARGIN, lFormTopcli.p)
-fmMetri.cs.IMaxAscender;
)

pchRowEnd = strpbrk( pchRow, "\n\r\xlA'');


)
return ;

Figure 1.5 (co7}££7}L4ecz)


24 OS/2 PRESENTATION MANAGER GPI

drawtext.c */
DrawText(HPS hps)

Reset the PS, erase the wl.ndow, set the CHARBUNDLE (character bundle)
attri.butes and draw some text.

Note that for most devl.ces the default character set 1.s a raster font
and several CHARBUNDLE attri.butes are 1.gnored for CM_MODEl raster
characters. For those devi.ces that provi.de a vector font as default
the character box attrl.bute should be set to the requl.red character
hei.ght l.n world coordl.nates. Character angle, dl.rectl.on and shear can
be defaulted.

i.nputs: hps Ps handle

P0INTL ptlposn /* coordi.nate posi.ti.on


SIZEF si.zfxcharBox /* character box si.ze
GRADIENTL gradlAngle /* character angle
P0INTL ptlshear /* character shear angle

/ ****************************************************************************** /
/**/
/* Reset the PS and erase the wl.ndow. */
/**/
/ ****************************************************************************** 1

Gpl.Resetps( hps /* -PS handle


GRES_ALL /* -Opt,.Ons
in
G p i. E r a s e ( h p s ) ; /* -PS handle

/ ****************************************************************************** I
/**/
/* Set the CHARBUNDLE attri.butes. */
/**/
/ ****************************************************************************** I

Figure 1.6 DrawText Function.


INTRODualoN: slMPLE TEXT AND GRAPHlcs OuTpuT 25

set foreground color


-PS handle
Gpi.Setcolor( hps
CLR_BLUE
-foreground color
n
set background color (i.gnored */
wi.th background ml.x BM_LEAVEALONE)*/
-PS handle
Gpi.SetBackcolor( hps
CLR_YELLOW
-background color
in
-set foreground mi.x
-PS handle
Gpi.SetMi.x( hps
-foreground ml.x mode
FM_OVERPAINT
in
set background ml.x (normally
BM_LEAVEALONE for si.mple text)
-PS handle
Gpi.SetBackMi.x( hps
BM_OVERPAINT
* -background mi.x mode

in
/* set character set (normally
/* default for si.mple text)
Gpi.Setcharset( hps /* -PS handle
LCID_DEFAULT /* -character set
in
/* set character mode (normally
/* default CM_MODEl for sl.mple text)
G p i. S e t C h a r M o d e ( hps /* -PS handle
CM MODE1 /* -character mode
in
/* set character box (l.gnored for
s I. z f x C h a r 8 o x . c x = MAKEFIXED(50,0); /* raster fonts: requi.red for all
s I. z fxc h a r 8 ox . cy = MAKEFIXED(50,0); /* outli.ne fonts I.n all modes)
G p I. S e t C h a r 8 o x ( hps /* -PS handle
& s i. z f x C h a r 8 o x /* -character box (50 x 50)
):

set character angle (l.gnored for


character mode CM MODEl and
gradlAngle.x = 2L; raster fonts; norffially default
gradlAngle.y = 1L: (1,0) for si.mple text)
-PS handle
Gpi.SetcharAngle( hps
&gradlAngle -character angle
):
set character di.rectl.on (i.gnored */
(for character mode CM_MODEl and */
raster fonts; normally default */
CHRDIRN_LEFTRIGHT for si.mple text)*/
Gpi.SetcharDi.rection( hps PS handle
CHDIRN_LEFTRIGHT character di.recti.on
in
set character shear (l.gnored
character mode CM MODEl and
ptlshear.x = 1L; raster fonts; normally uprl.ght
ptlshear.y = 5L; (0,1) for sl.mple text)
-PS handle
Gpl.Setcharshear( hps
&ptlshear -character shear
n

Figure 1.6 (con££7"ecz)


26 OS/2 PRESENTATION MANAGER GPI

1 ****************************************************************************** I
/**/
/* Draw some text. */
/**/
1****************************************************************************** I

ptlposn.x = SOL:
ptlposn.y = 100L;
Gpi.Move( hps /* -PS handle
&ptlposn /* -coordi.nate posi.ti.on
in

Gpl.Charstrl.ng( hps /* -PS handle


(LONG)(si.zeof("some text..)-1)
"some text"
in

return ;

Figure 1.6 (conffnL.ecz)

drawll.ne.c */
DrawLl.nes(HPS hps)

Reset the PS, erase the wl.ndow, set the LINEBUNDLE (line bundle)
attrl.butes and draw some ll.nes (note that those ll.ne bundle attrl.butes
whl.ch apply only to paths are not referenced by thl.s functl.on).

I.nputs: hps Ps handle

P0INTL ptlposn : /* coordl.nate posl.ti.on */

1 ****************************************************************************** I
/**/
/* Reset the PS and erase the wl.ndow. */
/**/
I ****************************************************************************** /

Gpl.Resetps( hps /* -PS handle


GRES_ALL /* -Optl'Ons
in
G p i. E r a s e ( h p s ) ; /* -PS handle

/ ****************************************************************************** I
/**/
/* Set the LINEBUNDLE attrl.butes. */
1**1

/ ****************************************************************************** I

Figure 1.7 DrawLines Function.


INTRODualoN.. slMPLE TEXT AND GRAPHlcs OuTpuT 27

Gpi.Setcolor( hps /* -PS handle */


CLR_BLUE /* -foreground color */
):

Gpi.SetMi.x( hps /* -PS handle */


FM_OVERPAINT /* -foreground ml.x mode */
in

Gpi.SetLi.newi.dth( hps /* -PS handle */


OxOOO10000 /* -cosmeti.c li.ne width (1.0) */
in

1 ****************************************************************************** 1
/**/
/* Draw some li.nes. */
/**/
/ ****************************************************************************** /

/* -PS handle
1 Posn /* -coordl.nate posi.ti.on

/* -PS handle
1 Posn /* -coordl.nate posl.tl.on

/* -PS handle
1 Posn /* -coordi.nate posl.ti.on

/* -PS handle
tl Posn /* -coordi.nate posi.ti.on

/* -PS handle
1 Posh /* -coordi.nate posi.ti.on

/* -PS handle
1 Posn /* -coordi.nate post.ti.on

return :

Figure I.7 (continuecL)


28 OS/2 PRESENTATION MANAGER GPI

drawarea.c */
ID DrawArea(HPS hps)

Reset the PS, erase the window, set the AREABUNDLE (area bundle)
attrl.butes and draw an area.

i.nputs: hps Ps handle

P0INTL ptlposn ; /* coordl.nate posl.ti.on


P0INTL ptlpatRef : /* pattern ori.gi.n

I ****************************************************************************** I
/**/
/* Reset the PS and erase the wi.ndow. */
/**/
/ ****************************************************************************** I

Gpi.Resetps( hps /* -PS handle


GRES_ALL /* -Optl'Ons
in
G p i. E r a s e ( h p s ) : /* -PS handle

/****************************************************************************** I
/**/
/* Set the AREABUNDLE attrl.butes. */
/**/
I ****************************************************************************** I

Gpl.Setcolor( hps /* -PS handle */


CLR_BLUE /* -foreground color */
in
/* set background color (l.gnored */
/* wi.th background ml.x BM_LEAVEALONE)*/
Gpi.SetBackcolor( hps /* -PS handle */
CLR_YELLOW /* -background color */
in
/* -set foreground mi.x */
Gpi.SetMl.x( hps /* -PS handle */
FM_OVERPAINT /* -foreground mi.x mode */
n
/* set background mi.x
Gpi.SetBackMi.x( hps /* -PS handle
BM_OVERPAINT /* -background mi.x mode
in
/* set pattern set
Gpi.Setpatternset( hps /* -PS handle
LCID_DEFAULT /* -pattern set
in
attern symbol
Gpi.Setpattern( hps andl e
PATSYM_DIAGl rn symbol
in

ptlpatRef.x = OL:
ptlpatRef.y -OL: /* set pattern orl.gl.n
Gpi.SetpatternRefpoi.nt( hps /* -PS handle
&ptlpatRef /* -pattern reference poi.nt
);

Figure 1.8 DrawArea Function.


INTRODUCTION: SIMPLE TEXT AND GRAPHICS OUTPUT 29

/ ****************************************************************************** 1
/**/
/* Drawan area. */
/**/
I ****************************************************************************** 1

ptlposn.x = 50L;
ptlposn.y = 100L;
Gpi.Move( hps /* -PS handle */
&ptlposn /* -coordl.nate posl.ti.on */
in

Gpi.Begi.nArea( hps /* -PS handle */


( BA_N 0 B 0 U N DA RY /* Optl'ons */
BA_A LT E RN AT E )

/* -PS handle
tl Posn /* -coordi.nate posi.ti.on

/* -PS handle
/* -coordl.nate posl.tl.on

/* -PS handle
&ptlposn /* -coordi.nate posi.ti.on
);

Gpi EndArea ( hps ) ;

return :

Figure 1.8 (co7i££7iL4ecz)


30 OS/2 PRESENTATION MANAGER GPI

drawmark.c */
ID DrawMarkers(HPS hps)

Reset the PS, Erase the wl.ndow, set the MARKERBUNDLE (marker bundle)
attri.butes and draw some markers.

i.nputs: hps Ps handle

P0INTL ptlposn ; /* coordl.nate posi.ti.on


SIZEF sl.zfxMkrBox : /* marker box sl.ze

I ****************************************************************************** I
/**/
/* Reset the PS and erase the wi.ndow. */
/**/
1 ****************************************************************************** 1

Gpi.Resetps( hps /* -PS handle


GRES_ALL /* -Optl'Ons
in
G p 1. E r a s e ( h p s ) : /* -PS handle

/****************************************************************************** /
/**/
/* Set the MARKERBUNDLE attrl.butes. */
/**/
/ ****************************************************************************** /

/* set foreground color


Gpl.Setcolor( hps /* -PS handle
CLR_BLUE /* -foreground color
in
set background color (i.gnored */
wi.th background mi.x BM_LEAVEALONE)*/
Gpl.SetBackcolor( hps PS handle
CLR_YELLOW background color
):
set foreground ml.x
Gpi.SetMi.x( hps PS handle
FM_OVERPAINT foreground mi.x mode
in
/* set background mi.x (normally
/* BM_LEAVEALONE for sl.mple markers)
Gpl.SetBackMi.x( hps /* -PS handle
BM_OVERPAINT /* -background ml.x mode
in
/* set marker set
Gpi.SetMarkerset( hps /* -PS handle
LCID_DEFAULT /* -marker set
);
/* set marker symbol
Gpi.SetMarker( hps /* -PS handle
MARKSYM_CROSS /* -character mode
in

sl.zfxMkrBox.cx = MAKEFIXED(50,0) /* set marker box (l.gnored for base */


si.zfxMkrBox.cy = MAKEFIXED(50,0) /* marker set and raster font markers*/
Gpl.SetMarkerBox( hps /* -PS handle */
&si.zfxMkrBox /* -marker box (50 x 50) */
in

Figure 1.9 DrawMarkers Function.


INTRODUCTION: SIMPLE TEXT AND GRAPHICS OuTPuT 31

1 ****************************************************************************** I
/**/
/* Draw some markers. */
/**/
I ****************************************************************************** I

/* -PS handle
/* -coordi.nate posi.tl.on

/* -PS handle
/* -coordi.nate posi.tl.on

/* -PS handle
/* -coordi.nate posi.ti.on

/* -PS handle
/* -coordl.nate posi.tl.on

/* -PS handle
/* -coordl.nate posi.tl.on

return :

Figure 1.9 (co7?£Znz/ecz)


32 OS/2 PRESENTATION MANAGER GPI

wcbl.tblt.c */
ID WCB1.tBlt(HPS hps, USHORT usBi.tmapld)

Reset the PS, erase the wi.ndow, set the IMAGEBUNDLE (i.mage bundle)
attri.butes and Bi.tBlt to the di.splay.

i.nputs: hps PS handle

#defl.ne XTARGET SOL


#defi.ne YTARGET 40L

HBITMAP hbm /* bi.tmap handle */


P0INTL aptlcoords[4] /* target/source coordi.nate array */
P0INTL ptlBmapsi.ze /* bi.tmap si.ze */
BITMAPINFOHEADER bmpData /* BITMAPINFOHEADER structure */

/************************************************************+***************** I
/**/
/* Load the bi.tmap. */
/**/
1 ****************************************************************************** 1

hbm = Gpi.LoadB1.tmap( hps


(HMODULE)NULL
usBi.tmapld
OL
OL

in

1 ****************************************************************************** /
/**/
/* Reset the PS and erase the wi.ndow. */
/**/
/ ****************************************************************************** I

Gpi.Resetps( hps /* -PS handle


GRES_ALL /* -Optl'Ons
n
G p i. E r a s e ( h p s ) ; /* -PS handle

I ****************************************************************************** /
/**/
/* Set the IMAGEBUNDLE attri.butes. */
/**/
/ ****************************************************************************** I

Figure 1.10 WCBitBlt Function.


INTRODUCTION: SIMPLE TEXT AND GRAPHICS OUTPUT 33

Gpl.Setcolor( hps /* -PS handle


CLR_BLUE /* -foreground color
n
set background color (i.gnored */
wi.th background mi.x BM_LEAVEALONE)*/
Gpi.SetBackcolor( hps -Ps handle */
CLR_YELLOW
-background color */
in
set foreground mi.x
Gpl.SetMi.x( hps PS handle
FM_OVERPAINT foreground mi.x mode
in
/* set background ml.x
Gpi.SetBackMi.x( hps /* -PS handle
BM_OVERPAINT /* -background mi.x mode
n
/ ****************************************************************************** /
/**/
/* Query the bl.tmap dl.mensions, convert to devi.ce coordl.nates (by */
/* subtracti.ng 1), convert to world coordi.nates and Bi.tBlt to the wi.ndow. */
/**/
/ ****************************************************************************** /

Gpi.OueryB1.tmapparameters( hbm /* -bi.tmap handle


&bmpData /* -BITMAPINFOHEADER structure
in
ptlBmapsi.ze.x = bmpData.cx -1;
ptlBmapsi.ze.y = bmpData.cy -1;
Gpi.Convert( hps
CVTC_DEVICE
CVTC_WORLD
1L
&ptlBmapsi.ze array
):

aptl coords [0] . x XTARGET ;


aptl coords [0] .y YTARGET ;
aptl coords [ 1 ] . x XTARGET + ptlBmapsi.ze.x;
aptl coords [ 1 ] .y YTARGET + ptlBmapsi.ze.y;
aptl coords [2] . x OL;

aptl coords [2] .y OL:


aptl coords [3] . x bmpData . cx ;
aptl coords [3] . y bmp
Gpi.WCBl.tBlt( hps /* -PS handle
.hbm /* -bi.tmap handle
4L /* -number of coordl.nate poi.nts
aptl Coords /* -coordi.nate poi.nts
ROP SRCCOPY /* -rop mi.x value
BBo_OR /* -Optl'Ons
);

/ ****************************************************************************** /
/**/
/* Delete the bi.tmap. */
/**/
/ ****************************************************************************** 1

Gpi. Del eteBi tmap ( hbm ) ;

return ;
)

Figure 1.10 (co77f£7iz/ecg)


34 OS/2 PRESENTATION MANAGER GPI

rotate.c */
Rotate(HPS hps)

Erase the wi.ndow, and rotate a fi.gure wi.th i.ts bottom left ori.gi.n
located at (100,150) 30.0 degrees counterclockwl.se about thi.s pol.nt
(usi.ng the model transform matri.x).

i.nputs: hps Ps handle

P0INTL ptlposn ; /* coordinate posi.ti.on


MATRIXLF matlfModel ; /* model transform matrl.x

/ ****************************************************************************** I
/**/
/* Erase the wi.ndow. */
/**/
1****************************************************************************** I

Gpi.Erase(hps); /* -PS handle */

1 ****************************************************************************** I
/**/
/* Construct and set the model transform matri.x to provi.de the requl.red */
/* rotati.on. */
/**/
/ ****************************************************************************** I

ptlposn.x = 100L;
ptlposn.y = 150L;
Gpi.Rotate( hps /* -PS handle
&matlfModel /* -transform matri.x
TRANSFORM_REPLACE /* -Optl'Ons
MAKEFIXED(30,0) /* -angle of rotation 30.0 deg.
&ptlposn /* -center of rotati.on
n
Gpi.SetModelTransformMatri.x( hps /* -PS handle */
9L /* -number of matri.x elements */
&matlfModel /* -transform matrl.x */
TRANSFORM_ADD /* -Optl`Ons */
in

I ****************************************************************************** I
/**/
/* Draw the figure. */
/**/
/ ****************************************************************************** 1

Figure 1.11 Rotate Function.


INTRODUCTION: SIMPLE TEXT AND GRAPHICS OUTPUT 35

/* -PS handle
tl Posn /* -coordl.nate posl.tl.on

/* -PS handle
1 Posn /* -coordi.nate posi.ti.on

/* -PS handle
tl Posn /* -coordi.nate posi.ti.on

/* -PS handle
tl Posn /* -coordl.nate posi.tl.on

return :

Figure 1.11 (co7}££7?L4ecz)

scale.c */
Scale(HPS hps)

Erase the wi.ndow, and scale a fi.gure wi.th 1.ts bottom left ori.gi.n
located at (100,150) by a factor of 2.01.n both x and y di.rectl.ons
(usi.ng the model transform matri.x).

i.nputs: hps Ps handle

P0INTL ptlposn /* coordl.nate posl.ti.on */


MATRIXLF matlfModel /* model transform matrl.x */
FIXED afxscale[2] /* x y scale factors */

/ ****************************************************************************** /
/**/
/* Erase the wl.ndow. */
/**/
/ ****************************************************************************** I

Gpi.Erase(hps); /* -PS handle */

1 ****************************************************************************** 1
/**/
/* Construct and set the model transform matrl.x to provl.de the required */
/* scaling. */
/**/
1 ****************************************************************************** I

Figure 1.12 Scale Function.


36 OS/2 PRESENTATION MANAGER GPI

afxscale[0] = MAKEFIXED(2,0): /* x scali.ng = 2.0


afxscale[1] = MAKEFIXED(2,0); /* y scall'ng -2.0
ptlposn.x = 100L:
ptlposn.y = 150L:
Gpi.Scale( hps /* -PS handle
&matlfModel /* -transform matri.x
TRANSFORM_REPLACE /* -Optl.Ons
afxscale /* -x and y scale factors
&ptlposn /* -center of scall.ng
in

Gpl.SetModelTransformMatri.x( hps /* -PS handle */


9L /* -number of matrl.x elements */
&matlfModel /* -transform matri.x */
TRANSFORM_ADD /* -Optl.Ons */
in

1 ****************************************************************************** I
/**/
/* Draw the fi.gure. */
/**/
/ ****************************************************************************** I

/* -PS handle
1 Posn /* -coordi.nate posl.ti.on

/* -PS handle
tl Posn /* -coordi.nate posi.ti.on

/* -PS handle
1 Posn /* -coordi.nate posi.tion

/* -PS handle
1 Posn /* -coordl.nate posl.tl.on

return :

Figure 1.12 (con££nz/ecz)


INTRODUCTION: SIMPLE TEXT AND GRAPHICS OUTPUT 37

translat.c */
ID Translate(HPS hps)

Erase the wl.ndow, and translate the picture by (50,100)


(usi.ng the model transform matri.x).

1.nputs: hps PS handle

P0INTL ptlposn ; /* coordl.nate posl.tl.on */


MATRIXLF matlfModel ; /* model transform matri.x */

/ ****************************************************************************** /
/**/
/* Erase the wl.ndow. */
/**/
/****************************************************************************** /

GpiErase(hps); /* -Ps handle */

/ ****************************************************************************** 1
/**/
/* Construct and set the model transform matrl.x to provl.de the requl.red */
/* translatl.on. */
/**/
/ ****************************************************************************** /

ptlposn.x = 50L:
ptlposn.y = 100L;
Gpi.Translate( hps /* -PS handle */
&matlfModel /* -transform matrl.x */
TRANSFORM_REPLACE /* -Optl'Ons */
&ptlposn /* -translati.on coordi.nates */
in

Gpl.SetModelTransformMatri.x( hps /* -PS handle */


9L /* -number of matri.x elements */
&matlfModel /* -transform matri.x */
TRANSFORM_ADD /* -Opt,'Ons */
in

/ ****************************************************************************** 1
/**/
/* Draw the fl.gure. */
/**/
/ ****************************************************************************** /

Figure 1.13 'Thanslate Function.


38 OS/2 PRESENTATION MANAGER GPI

/* -PS handle
1 Posn /* -coordi.nate posl.ti.on

/* -PS handle
1 Posn /* -coordi.nate posl.ti.on

/* -PS handle
1 Posn /* -coordi.nate posi.tl.on

/* -PS handle
1 Posn /* -coordi.nate posi.ti.on

return ;

Figure 1.13 (corif£7iztecz)


INTRODUCTION: SIMPLE TEXT AND GRAPHICS OUTPUT 39

dsppmerr.c */
ID Dl.splaypMError(HAB hab, PSZ pszstri.ng)

di.splay: PM Error / Severl.ty / Base OS/2 RC / PM Error Message

PM Error I.s a hex error code defl.ned i.n pmerr.h

Severi.ty i.s hex number and l.s one of : 0 (SEVERITY_NOERROR)


4 (SEVERITY_WARNING)
8 (SEVERITY_ERROR)
C (SEVERITY_SEVERE)
10 (SEVERITY_UNRECOVERABLE)

Base OS/2 RC l.s a decl.mal error number defi.ned i.n bseerr.h

PM Error Message 1.s a null terml.nated text strl.ng descrl.bl.ng the PM Error.

The pszstri.ng 1.nput parameter l.s aval.1able for use by the caller, for
example, to i.denti.fy the name of the PM call that failed.

CHAR achoutput[80] /* message stri.ng CHAR array


LONG erri.d /* error 1.d
SHORT sOS2Rc = 0 /* base (OS/2) return code
PSHORT psOS2Rc /* base (OS/2) return code pol.nter
PSZ pszErrMsg = ``'' /* PM error message poi.nter
PSHORT psoffset /* poi.nter offset
PERRINF0 perri.Info = NULL /* ERRINF0 poi.nter

/* get last error

errl.d = Wi.nGetLastError(hab);

/* i.f last error not 'ok. dl.splay error message box

l.f (ERRORIDERROR(errl.d) != PMERR_OK)


(

/* get error i.nfo */

perri.Info = Wi.nGetErrorlnfo(hab);

/* get PM error message pol.nter */

psoffset = MAKEP(SELECTOROF(perri.Info), (perri.Info->offaoffszMsg


+ OFFSETOF(perrl. Info) ) ) ;
pszErrMsg = MAKEP(SELECTOROF(perri.Info),
(*psoffset + OFFSETOF(perri. Info) ) ) ;

/* 1.f error code l.s PMERR_BASE_ERROR get base OS/2 error code */

I.f (ERRORIDERROR(erri.d) == PMERR_BASE_ERROR)


(

psOS2Rc = MAKEP(SELECTOROF(perrl.Info), (perrl.Info->offB1.naryData


+ OFFSETOF(perrl. Info) ) ) ;
sOS2Rc = *psOS2Rc ;
)
)

Figure 1.14 DisplaypMError Function.


40 OS/2 PRESENTATION MANAGER GPI

/* format the message stri.ng

sprl.ntf(achoutput,"%x/%x/%d/%s %s\n",
E R R 0 R I D E R R 0 R ( e r r i. d ) , /* PM error code
ERRORI DSEV ( erri d ) , /* severl'ty
sOS2Rc , /* base OS/2 error number
pszErrMsg , /* PM error message
p s z S t r 1' n 9 ) ; /* callers string

/* dl.splay the error

Wi.nMessageBox( HWND_DESKTOP /* parent wl.ndow


NULL /* owner wi.ndow
I achoutput /* message text
"Error/Severi.ty/OS2RC/ErrMsg" /* message box tl.tle
1 /* message box i.d
M B_C U AC R I T I C A L /* wl.ndow style
MB SYSTEMMODAL
MB_oK

/* free the error l.nfo

if (perrl.Info)
W i. n F r e e E r r o r I n f o ( p e r r 1. I n f o ) ;

return ;

Figure 1.14 (co7}££7?ztecz)


Presentation Spaces and Device Contexts

In order to perform any GPI Drawing operation to an output device, a device


context or DC is required for the device. This must be linked to, or associated with,
a presentation space or PS.

DEVICE CONTEXTS

A DC represents the particular instance of a shared output device to which the


drawing from an application is directed. A printer, for example, would be shared
by all applications wishing to produce printed output and each application would
create its own printer DC to which its output would be directed. In the case of a
display, different applications, or different parts of the same application, would
require their output to be directed at different windows on the screen. To accom-
plish this, each would open a DC for its own particular target window and direct
its output at this (window) DC.
A DC can be regarded as a logical output device consisting of a block of memory
containing device state information relating to a particular job. This includes such
things as window origin, picture orientation, current drawing color, current x,y
position and so forth. DCs fall into the following groups:

Display Window DCs

Display window DCs are created explicitly or, if already created previously,
queried using:
WinopenwindowDC; and
WinQuerywindowDC.

41
42 OS/2 PRESENTATION MANAGER GPI

Display window DCs are also implicitly allocated along with a presentation space
(see below) by:
WinGetps;
WinGetclipps;
WinGetscreenps; and
WinBeginpaint.
All display DCs are window DCs and the window must first be created to enable
its handle to be passed as a parameter to these functions. Display DCs are the only
DCs not created using DevopenDC.

Queued DCs

Queued DCs are used for printing and plotting queued output via the spooler and
are created using DevopenDC with a DC-type parameter of OD_QUEUED.

Direct DCs

Direct DCs are used for printing and plotting directly to a device ®ypassing the
spooler) and are used by the system to print queued print ].obs as they are
dequeued from the print queue. Direct DCs should not normally be used by
applications as, unlike queued DCs, they do not enable an output device to be
properly shared between different applications. Direct DCs are created using
DevopenDC with a DC-type parameter of OD_DIRECT.

Info DCs

Info DCs can be created for any device and have all the characteristics of a normal
DC but produce no output to the device. They have a smaller memory overhead
than a normal DC and exist solely for querying device information (e.g., device
capabilities, device fonts, printer forms, character positioning information). Info
DCs are created using DevopenDC with a DC-type parameter of OD_INFO.

MetaFile DCs

MetaFile DCs are used to record drawing primitives and resources (fonts, color
tables, etc.) in a MetaFile for interchange purposes. When the MetaFile DC is
closed, a memory MetaFile is established and its handle returned to the applica-
tion. The memory MetaFile can then be drawn, passed to other applications via
the clipboard, or saved in application memory or as a file for interchange. MetaFile
DCs are created using DevopenDC with a DC-type parameter of OD_METAFILE
or OD METAFILE_NOQUERY. These two types are the same except that the
latter provides better recording performance at the expense of not allowing
drawing attribute values to be queried.
PRESENTATION SPACES AND DEVICE CONTEXTS 43

Memory DCs

Memory DCs are required for bitmap operations. A bitmap is selected into a
Memory DC in order to draw to it or use it as the target or source of BitBlt
operations. Memory DCs are created using DevopenDC with a DC-type parame-
ter of OD MEMORY.
See Appendix 1 for a full description of DevopenDC parameters.

PRESEHTATIOH SPACES

In order to output to a device, an application requires a presentation space or PS


associated with the target DC. The purpose of the PS is to retain device indepen-
dent data (in addition to that retained by the DC) and resources between applica-
tion calls. The application will store the PS handle and, once the PS and DC are
associated, the PS will store the (associated) DC handle. The DC in turn holds a
handle to an extension of the DC known as the Device Drawing Context (DDC)
which is owned by the Hesentation Driver (in the early days of Driver Interface
definition this DDC handle or hddc was refeITed to as the`Magic Cookie'). This is
illustrated for both a Norm.al-PS and Micro-PS in Figures 2-1 and 2-2. There are
three different types of PS:

Micro-PS

Applications, for which a DC alone can retain all the necessary information still
require a PS for consistency but a simple PS, called a Micro-PS, will suffice. A
Micro-PSispermanentlyassociatedwithitsDCandthePSpartofthisPsrocpair
effectively contains only handles of the associated DC and PS resources. A Micro-
PS therefore minimizes the amount of memory required and is fast to create. It
does, however, offer significantly less function than a Normal-PS. A Micro-PS
should be used in preference to a Normal-PS whenever possible.

Normal-PS

A Normal-PS supports all GPI functions. Uhiike a Micro-PS, it can be disassoci-


ated from one DC and associated with another. For example, an application
drawing to a window might wish to disassociate the PS from the window DC and
associate it with a printer or MetaFile DC in order to print the picture or record it
in a MetaFile. A Normal-PS should only be used for applications that require
functions not supported by a Micro-PS.

Cached Micro-PS

A variation of the Micro-PS is the cached Micro-PS. An application that creates a


large number of windows, and permanently allocates a DC for each, will rapidly
deplete the total number of available DCs for the process. This is resolved by use
ofacachedMicro-PSthatisintendedforusewithwindowsrequiringaPSandDC,
britrequiringnoinformationtoberetained(otherthanthatvisibleonthedisplay)
between each sequence of output operations.
44 0S/2 PRESENTATION MANAGER GPI

GPI ORE DDI


Appllcatlon Graphlcs PreBentatlon
En8ln® (Device) I)river
Application
I)ate

I)evlc®
Dravlng
Context

Figure 2.1 Normal-PS and DC Data Objects.

A cached Micro-PS is really a Psroc pair. Unlike a No]rm.al-PS or uncached


Micro-PS, the DC part of this PS/DC pair is allocated with the PS from a cache and
does not need to be explicitly created. Otherwise a cached Micro-PS is very similar
to an uncached Micro-PS. It can be rapidly allocated (and reinitialized) and
deallocated and does not need to be permanently tied to a particular window. As
soon as one sequence of output operations is complete, it should be returned to the
cache (i.e., before the relevant Window Procedure completes), making it available
for use with other windows. A cached Micro-PS may only be used with display
windows, whereas an uncached Micro-PS can be used with any output device. A
cached Micro-PS should be used by applications that need a large number of
windows and require the same PS and DC to be shared by different windows.

PS CREATION AND ASS00IATI0II

A Normal-PS or (uncached) Micro-PS is created and optionally associated using:


Gpicreateps
A full description of the Gpicreateps parameters is provided later in this chapter.
PRESENTATION SPACES AND DEvlcE cONTEXTs as

GPI DDI
Appllcatlon Pr®Bentatlon
Driver

D®vlce
D"t,in8
Context

Figure 2.2 Micro-PS and DC Data Objects.

ANormal-PScanbeassociatedwithaDCand,byspecifyingaNULLDChandle,
disassociated using:
GpiAssociate
As mentioned earlier, a cached Micro-Psroc pair is obtained using:
WinGetps;
WinGetclipps;
WinGetscreenps; and
WinBeginpaint.
WinGetclipps is similar to WinGetps but provides additional clipping.
WinReleaseps must be used with WinGetps/WinGetclipps/WinGetscreenps in
order to return the Psroc pair to the cache. WinBeginpaint and WinGetscreenps
are both for specialized use as described below.
WinBeginpaint is provided for responding to WM_PAINT messages to ensure
that the relevant parts of a window are correctly repainted when `healing' is
required (for example, when an overlaying window is removed). Note that when
an existing PS is available, its handle should be passed to WinBeginpaint as a
parameter rather than requesting the system to allocate a new cached Micro-PS.
Otherwise, a cached Micro-PS can be requested by specifying the PS handle
parameter as NULL prompting WinBeginpaint to allocate a cached Micro-PS and
return its handle. WinEndpaint must follow WinBeginpaint to signal completion
of WM_PAINT processing and to return any cached Psroc pair to the cache.
46 0S/2 PRESENTATION MANAGER GPI

WinGetscreenps will return a cached Psroc pair for the Desk Top window (i.e.,
the entire display screen). This function might be used, for example, by an
application wishing to capture the entire screen in a bitmap for printing. This
function makes it possible for an application to write over any part of the display
screen, including windows owned by other applications, and should, therefore,
only be used with extreme caution. Otherwise, use of WinGetscreenps is the same
as for WinGetps.

GPISETPS

Although the PS page size, page units, and long/short coordinate format specified
on Gpicreateps will often remain unchanged for the life of the PS, they can be
modified together with an optional PS reset using Gpisetps. However, certain
restrictions apply to the use of this function. In particular, it should not be used
for a PS associated with a DC of type OD_QUEUED with data type PM_Q_STD
(see chapter 12), or with a DC of type OD_METAFIIE or OD_METAFILE_NOQU-
ERY (see chapter 11).

SUMMARY OF PS AHD DC CREATION AND ASSOCIATION

Display Window DC

This is created using WinopenwindowDC and destroyed with the window by


WinDestroywindow. Once opened it can be subsequently queried using
WinQuerywindowDC.

Non-Display Window DC

This is created and destroyed using DevopenDC and DevcloseDC.

Normal-PS or uncached Micro-PS


These are created and destroyed using Gpicreateps and GpiDestroyps.

Association of DC and a Normal-PS or an uncached Micro-PS


This is performed using GpiAssociate (for a Normal-PS only) or Gpicreateps with
the GPIA_ASSOC option. Disassociation of a Normal-PS and DC is performed
using GpiAssociate with a NULL DC handle. A Micro-PS cannot be disassociated
from its DC except by destroying the PS.

Allocation/De-Allocation of cached Micro-PS/DC pair for a window

This is performed using WinGetps/WinGetclipps and WinReleaseps.

AIlocation/De-AIIocation of cached Micro-PS/DC for WM_PAINT processing

This is performed using WinBeginpaint and WinEndpaint with the


WinBeginpaint PS handle parameter specified as NULL.
PRESENTATION SPACES AND DEVICE CONTEXTS 4]

Use of an existing PS and associated window DC for WM_PAINT processing

This is performed using WinBeginpaint and WinEndpaint with the


WinBeginpaint PS handle parameter specified as the handle of the existing PS.

AIlocation and De-AIIocation of cached Micro-PS/DC pair for the desktop

This is performed using WinGetscreenps and WinReleaseps.

A selection of these operations are illustrated by the Functions in Figures 2-3 to


2-7.

GPICREATEPS PARAMETERS

The Gpicreateps parameters are as follows:

HPS Gpicreateps ( IIAB hab


HDC hdc
PSIZEL psizlps
ULONG floptions
);

nab

This is the anchor block handle returned by Winlnitialize.

hdc

If the GPIA_ASSOC option is specified, this is the handle of the DC with which
the newly created PS is to be associated. If GPIA_NOASSOC is specified this can
be specified as NULL.

psizlps
This specifies the size of the PS page in page units. The marimun. permissible
value for either dimension is Ox07FFFFFF (or 134217727). If GPIA ASSOC is
specified, either or both dimensions may be specified as zero causing them to be
defaulted to a size determined by the associated device output area. If this is a
display window then the defaults are deter.mined by the the screen dimensions. If
the page units are PU_ARBITRARY and only one dimension is defaulted, its value
is set to that which ensures that the picture aspect ratio is preserved. Where both
dimensions are defaulted, the default values are determined by the device pel
dimensions. The actual values of the PS page dimensions are only important in
certain cases as follows:
48 OS/2 PRESENTATION MANAGER GPI

1. If pu_ARBITRARY page units are specified then the ps page dimen-


sions represent the drawing limits that will be visible on the output
media.
2. If Gpisetpageviewport is to be issued then the PS page dilnensions
together with the new page viewport will determine the new device
transformi matrix and page units.
3. If the PS is to be used to record a MetaFile then the PS page dimen-
sions will be recorded in the MetaFile as the picture dimensions. These
dimensions might be used when the MetaFile is redisplayed.
4. If the `ARE=' and `FIT=' print queue processor parameters are used to
scale to fit or specify the position or size of the output area during
printing, then any picture scaling and so forth, will be performed using
the PS page dimensions.
It is recommended that very small PS page dimensions (e.g., 2x2) should not be
used. Ideally, the dimensions should either be defaulted or reflect the size of the
preferred output media (maximized display window, printer form size, etc.). See
chapter 7 for a more complete description of PS page size.

floptions
This specifies a combination of the following:
PS_UNITS specifies page units as one of:
PU_ARBITRARY;
PU_PELS;
PU LOMETRIC;
PU_HIMETRIC;
PU_LOENGLISH;
PU_HIENGLISH; and
PU TWIPS.
See chapter 7 for a description of page units.
PS_FORMAT specifies the long or short retained segment and MetaFile world
coordinate format as one of:
GPIF_LONG (coordinate range is OxF8000000rox07FFFFFF);
GPIF_SHORT (coordinate range is OxFFFF8000rfu00007FFF); and
GPIF_DEFAULT (= GPIF_LONG).
This option controls the size of coordinates stored in the drawing orders of
retained graphics segments and MetaFiles and is ignored for non-retained graph-
ics output. Coordinates stored in GPIF_SHORT format require less memory but it
is the responsibility of the application to ensure that truncation of 32 bit primitive
coordinates to 16 bit order coordinates does not result in loss of data (for example,
PRESENTATION SPACES AND DEVICE CONTEXTS 49

a large positive value greater than 32767 could appear negative after truncation).
For performance reasons this checking is not performed by the system.
PS_TYPE specifies the type of PS (i.e., Micro-PS or Normal-PS) as one of:
GPIT_MICRO; and
GPIT NORhEL.
PS_ASSOC specifies association or no association as one of:
GPIA_ASSOC (mandatory for GPIT_MICRO); and
GPIA NOASSOC.
PS_MODE (the mode option) is not used.

Return Value

The handle of the newly created PS is returned or, if an error was detected, the
error is logged and a NULL PS handle (i.e., GPI_ERROR) is returned.

PS AND D0 00HTROL AND QUERY FUMOTI0NS

A number of useful PS control and query functions are provided, several of which
are used in the examples throughout this book.

DevEscape
DevEscape is provided to enable data to be sent directly to or received directly from
a FTesentation (device) Driver, bypassing the GPI. Escape codes may be unique to
a particular driver but a number of predefined codes exist. The most commonly
used are DEVESC STARTDOC, DEVESC ENDDOC, DEVESC ABORTDOC,
DEVESC_NEWFRdrE and DEVESC_RAwi)ATA, which are usea for printing.
DEVESC_STARTDOC and DEVESC_ENDDOC are in fact mandatory for print
jobs and DEVESC_RAWDATA is used to pass raw data (e.g., ASCII text for most
printers) to a Hesentation Driver. When a DevEscape function is issued to a
MetaFile or PM_Q_STD/OD_QUEUED DC, depending on the escape code value,
the function is either processed ilnlnediately by the driver or recorded in the
MetaFile or print file. The action taken for the different escape code ranges is as
follows:

Ongl49 processed immediately for all DC types.


8150-16299 recorded in MetaFile and processed
immediately for OD_QUEUED DC.
16300-24449 recorded in both MetaFile and print file.
24450-32599 recorded in print file and processed
immediately for MetaFile DC.
32600-32767 reserved.
50 OS/2 PRESENTATION MANAGER GPI

3276840959 processed immediately for all DC types.


4096049151 recorded in MetaFile and processed
i-ediately for OD_QUEUED DC.
49152-57343 recorded in both MetaFile and print file.
57344rfe5535 recorded in print file and processed
immediately for MetaFile DC.
Use of DevEscape is illustrated by a number of the examples in this book.

DevQuerycaps

DevQuerycaps enables the device characteristics (e.g., resolution) to be deter-


mined for a particular device.

GpiErase

GpiErase is intended primarily for use with displays to erase the window to
background color.

GpiQueryDevice

GpiQueryDevice is a useful function that returns the handle of the DC associated


with a specified PS. Certain PM functions (e.g., DevEscape) require a DC handle
as a parameter and this function avoids the need to include the DC handle as
parameter to application functions in addition to the PS handle.

GpiResetps

GpiResetps resets the presentation space. Three levels of reset are available:
GRES_ATI`RS resets the picture drawing attributes to default.
GRES_SEGMENTS, in addition to performing a GRES_ATrRS
reset operation, destroys all retained graphics segments and resets
all PS environment attributes (e.g., default viewing transform, de-
fault drawing attributes) to their initial value. I.ogical font and color
table resources are preserved.
GRES_ALL performs a full presentation space reset destroying all
resources (i.e., logical fonts and color tables) in addition to perform-
ing GRES_ATTRS and GRES_SEGMENTS reset operations.

Gpisaveps/GpiRestoreps

These are fairly coarse save and restore functions included mainly for compatibil-
ity. As they save and restore a combination of both picture and environment
PRESENTATION SPACES AND DEVICE CONTEXTS 51

information they do not fit tidily into the `picture and environment' model de-
scribed in chapter 1. For this reason, they cannot be used with retained graphics
segments and, if used for recording a MetaFile, will produce a MetaFile that does
not correctly conformi to the interchange architecture.

nmpsdraw.c */
OL NormalpsDraw(HWND hwnd, PDEVOPENDATA pdopData)

Use a Normal-PS to draw to a di.splay wl.ndow followed by a pri.nter as


f ol 1 ows :

Query the anchor block handle.


Obtai.n a wi.ndow DC handle for the wi.ndow.
Create a Normal-PS and assocl.ate wl.th the wi.ndow DC.
Draw to the PS.
Di.ssoci.ate the PS from the wi.ndow DC.
Create an OD_QUEUED DC for the prl.nter.
Associ.ate the PS and the pri.nter DC.
Issue 'start document' DevEscape requi.red by the prl.nter.
Draw to the PS.
Issue 'end document' DevEscape.
Di.ssoci.ate the PS from the pri.nter DC.
Destroy the PS.
Close the pri.nter DC.

Figure 2.3 NormalpsDraw Function.


52 OS/2 PRESENTATION MANAGER GPI

/* 1.nputs: hwnd Wi.ndow handle */


pdopData Complete DEVOPENSTRUC structure for the target pri.nter */
(see Prl.ntDefprl.nter)

"wi.ndow text..
#defl.ne CHSTRW
#defi.ne NCHRSW ( LONG ) ( s I. zeof ( CHSTRW ) -1 )
``printer text..
#defi.ne CHSTRP
#defi.ne NCHRSP ( LONG ) ( s i zeof ( CHSTRP ) -1 )
"Prl.nt Job"
#defi.ne PDOCNAME
#defi.ne PDOCNAMELEN ( LONG ) s 1. zeof ( PDOCNAME )

HAB hab /* anchor block handle


HDC hdcwnd = NULL /* di.splay wi.ndow DC handle
/* PS handle
!8§L :R:t =E#s:RROR /* B00L return code
HDC hdcprt = DEV_ERROR /* prl.nter DC handle
B00L fRetA = FALSE /* B00L Gpl.Associ.ate return code
LONG I Length /* ENDDOC returned data length
USHORT usJobld /* ENDDOC returned job 1.d
SIZEL sizlps /* PS page si.ze
P0INTL ptlcoord /* coordi.nate pol.nt

/* obtal.n the anchor block handle */


hab = WinoueryAnchorBlock(hwnd); /* -wi.ndow handle */

i f ( hab ! =NU LL ) /* obtai.n a DC for the wi.ndow


hdcwnd = Wl.nQuerywi.ndowDC(hwnd) /* -wi.ndow handle
if (hdcwnd==NULL)
hdcwnd = Wi.nopenwi.ndowDC(hwnd); /* -wi.ndow handle

s I. z 1 P S . cx=O L : /* set PS di.mensi.ons = zero


s i z 1 PS . cy-0 L : /* (i..e. default)
I.f (hdcwnd!=NULL) /* create PS and assocl.ate
hps = Gpl.Createps( hab /* -anchor block handle
. hdcwnd /* -DC handle
& s 1' Z i P S /* -presentati.on page S1.Ze
PU_PELS /* -Optl.Ons
G P I F_D E FAU LT
GPIT NORMAL
GPIA_ASSOC
in

ptlcoord.x = 100L:
ptlcoord.y = 100L;
I.f (hps!=GPI_ERROR)
fRet = (B00L)Gpi.Charstrl.ngAt
p O 1' n t
characters
s t r 1' n 9

I.f (hps!=GPI_ERROR) /* di.ssoci.ate PS & wi.ndow DC


fRet = Gpi.Associ.ate( hps /* -PS handle
NULL /* -DC handle (= NULL)
) && fRet;

Figure 2.3 (co7?fz7?zJecz)


PRESENTATION SPACES AND DEVICE CONTEXTS 53

l'f (fRet) /* create pri.nter DC


hdcprt = DevopenDC( hab /* -anchor block handle
OD_QUEUED /* -DC type
* ,, /* -token
9L /* -count of pdopData elements
pdopData /* -Open DC data
NULL /* -compatl.ble hdc (n/a)
in

1.f (hdcprt!=DEV_ERROR) /* assocl.ate PS and prl.nter DC


fRet = (fRetA = Gpi.Associ.ate( hps /* -PS handle
hdcprt /* -DC handle
Em
l`f (fRet) /* i.ssue 'start document' DevEscape */
fRet = DevEscape( hdcprt /* -DC handle */
DEVESC_STARTDOC /* -escape code */
PDOCNAMELEN /* -si.ze of document name */
PDOCNAME /* -null terml.nated document name */
NULL /* -sl.ze of output data (not used)*/
NULL /* -output data (not used) */
) --DEV_OK:

ptlcoord.x = 100L;
ptlcoord.y = 100L:
l'f (fRet)
fRet = (B00L)Gpl.Charstri.ngAt
p o l' n t
characters
s t r 1' n 9

1 Length 2L;
1' f ( f R e t ) /* I.ssue lend document' DevEscape
f Ret = DevEscape( hdcprt /* -DC handle
DEVESC_ENDDOC /* -escape code
OL /* -length of i.nput data (OL)
NULL /* -1.nput data (not used)
&lLength /* -si.ze of output data (2L)
(PBYTE)&usiJobld /* -output data (returned job 1.d)
) --DEV_OK;

l`f (fRetA) /* dl.ssoci.ate PS and prl.nter DC */


fRet = Gpi.Associ.ate( hps /* -PS handle
NULL /* -DC handle (= NULL)
) && fRet;

I.f (hps!=GPI_ERROR) /* destroy PS


fRet = Gpl.Destroyps(hps) && fRet; /* -PS handle

i.f (hdcprt!=DEV_ERROR) /* destroy pri.nter DC


fRet = DevcloseDC( hdcprt /* -DC handle
) != DEV_ERROR && fRet;

return ( fRet ) ;

Figure 2.3 (con££77L4ecz)


54 OS/2 PRESENTATION MANAGER GPI

upswdraw.c */
OL Ml.cropswl.ndowDraw(HWND hwnd)

Use a non cached Mi.cro-PS to draw to a di.splay wi.ndow as follows:

Query the anchor block handle.


Obtal.n a wi.ndow DC handle for the window.
Create a Mi.cro-PS and associ.ate wi.th the wi.ndow DC.
Draw to the PS.
Destroy the PS.

i.nputs: hwnd Wi.ndow handle

#defl.ne CHSTRMW "wi.ndow text"


#defi.ne NCHRSMW (LONG)(sl.zeof(CHSTRMW)-1)

HDC hdcwnd = NULL /* wi.ndow DC handle


HPS hps = GPI_ERROR /* PS handle
B00L fRet = FALSE /* B00L return code
SIZEL si.zlps /* PS page size
P0INTL ptlcoord /* coordl.nate poi.nt

/* obtai.n the anchor block handle */


hab = Wl.nQueryAnchorBlock(hwnd); /* -wl.ndow handle */

I. f ( h a b ! = N U L L ) /* obtai.n a DC for the wi.ndow */


hdcwnd = Wl.nQuerywi.ndowDC(hwnd) /* -wi.ndow handle
I.f (hdcwnd==NULL)
hdcwnd = Wi.nopenwi.ndowDC(hwnd); /* -wi.ndow handle

s I. z 1 P S . cx=O L ; /* set PS di.mensi.ons = zero


s 1. z 1 PS . cy=O L ; /* (i..e. default)
i.f (hdcwnd!=NULL) /* create Mi.cro-PS and assocl.ate
hps = Gpi.Createps( hab /* -anchor block handle
. hdcwnd /* -DC handle
& s 1' z 1 P S /* -presentati.on Page sl.ze
PU PELS /* -Optl.Ons
G P I F_D E FAU LT
G P I T_M I C R0
GPIA_ASSOC
in

ptlcoord.x = 100L;
ptlcoord.y = 100L;
if (hps!=GPI_ERROR)
fRet = (B00L)Gpi.Charstri.ngAt
p 0 1' n t
characters
s t r 1` n 9

i.f (hps!=GPI_ERROR) /* destroy the Mi.cro-PS


fRet = Gpi.Destroyps(hps) && fRet; /* -PS handle

return ( fRet ) ;

Figure 2.4 MicropswindowDraw Function.


PRESENTATION SPACES AND DEVICE CONTEXTS 55

/* upsndraw.c */
B00L Mi.cropsNonDi.splayDraw(HAB hab, PDEVOPENDATA pdopData)
(
/* Usi.ng a non-cached Mi.cro PS, draw to a non-di.splay pri.nter devi.ce as
/* follows:
/*
/* Obtai.n a DC for the pri.nter.
/* Create a Ml.cro-PS and associate wl.th the prl.nter DC.
/* Issue 'start document' DevEscape requi.red by the pri.nter.
/* Draw to the PS.
/* Issue lend document' DevEscape.
/* Di.ssoci.ate the PS from the pri.nter DC.
/* Destroy the PS.
/* Close the pri.nter DC.
/*
/* I.nputs: hwnd Wi.ndow handle
/* pdopData Complete DEVOPENSTRUC structure for the target pri.nter
/* (see PrintDefpri.nter)
/*

#defi.ne CHSTRN .`pri.nter text..


#defi.ne NCHRSN (LONG)(si.zeof(CHSTRN)-1)
#defi.ne NDDOCNAME "Pri.nt Job"
#defi.ne NDDOCNAMELEN (LONG)si.zeof(NDDOCNAME)

HDC hdcprt /* prl.nter DC handle


/* PS handle
i:SL [R:t =Efi3[RROR /* B00L return code
P0INTL ptlcoord /* coordl.nate pol.nt
SIZEL si.zlps /* PS page si.ze
LONG 1 Length /* length of returned job i.d
USHORT usJobld /* returned pri.nt job i.d

/* open non-window DC
hdcprt = DevopenDC( hab /* -anchor block handle
OD_OUEUED /* -DC type
* ,, /* -token
9L /* -count of pdopData elements
pdopData /* -Open DC data
NULL /* -compati.ble hdc (n/a)
n
S1.Zips.CX = Sl.Zips.Cy = OL:
I.f (hdcprt != DEV_ERROR) /* create Mi.cro PS and assocl.ate
hps = Gpi.Createps( hab /* -anchor block handle
hdcprt /* -DC handle
&sl`zlps /* -PS page sl.ze
PU_PELS /* -Optl'Ons
GP I F_D E FAU LT
GPIT MICRO
GPIA-ASSOC
);

if (hps!=GPI_ERROR) /* i.ssue 'start document' DevEscape */


fRet = DevEscape( hdcprt /* -DC handle */
DEVESC_STARTDOC /* -escape code */
NDDOCNAMELEN /* -si.ze of document name */
NDDOCNAME /* -null termi.nated document name */
NULL /* -si.ze of output data (not used)*/
NULL /* -output data (not used) */
) --DEV_OK:

Figure 2.5 MicropsNonDisplayDraw Function.


56 OS/2 PRESENTATION MANAGER GPI

ptlcoord.x = 100L:
ptlcoord.y = 100L;
l'f (fRet)
fRet = (B00L)Gpi.Charstri.ngAt
poi nt
characters
s t r 1' n 9

lLength = 2L:
1' f ( f R e t ) /* i.ssue 'end document' DevEscape
fRet DevEscape( hdcprt /* -DC handle
DEVESC_ENDDOC /* -escape code
OL /* -length of 1.nput data (OL)
NULL /* -i.nput data (not used)
&lLength /* -sl.ze of output data (2L)
(PBYTE)&usJobld /* -output data (returned job 1.d)
) --DEV_OK;

I.f (hps != GPI_ERROR) /* destroy the PS


fRet = Gpl.Destroyps(hps) && fRet; /* -PS handle

1.f (hdcprt != DEV_ERROR) /* close the DC


fRet = DevcloseDC( hdcprt /* -DC handle
) != DEV_ERROR && fRet;

return ( fRet ) ;

Figure 2.5 (continued)


PRESENTATION SPACES AND DEVICE CONTEXTS 57

cachdraw.c */
OL CachedMi.cropswi.ndowDraw(HWND hwnd)

Use a Cached Mi.cro-PS to draw to a dl.splay wl.ndow as follows:

Get cached Mi.cro-PS/DC pal.r.


Draw to the wi.ndow.
Release the cached PS/DC pal.r

l.nputs: hwnd Wi.ndow handle

#defi.ne CHSTRC "wi.ndow text"


#defi.ne NCHRSC (LONG)(si.zeof(CHSTRC)-1)

HPS hps /* PS handle


B00L fRet = FALSE /* B00L return code
P0INTL ptlcoord /* coordi.nate pol.nt

/* get cached PS/DC pal.r


hps = Wi.nGetps(hwnd): /* -wl.ndow handle

ptlcoord.x = 100L:
ptlcoord.y = 100L:
l.f (hps!=NULL)
fRet = (B00L)Gpi.Charstri.ngAt( hps
&ptlcoord p o l' n t
NCHRSC characters
CHSTRC s t r 1' n 9
in

l.f (hps!=NULL) /* release cached PS/DC pal.r */


fRet = Wi.nReleaseps(hps) && fRet; /* -PS handle */

return ( f Ret ) ;

Figure 2.6 CachedMicropswindowDraw Function.


58 OS/2 PRESENTATION MANAGER GPI

pwmpai.nt.c */
OL Processwmpai.nt(HWND hwnd, HPS hps)

Perform WM_PAINT processi.ng. If hps 1.s NULL a cached Mi.cro-PS 1.s allocated
and used for the pal.nt. If hps l.s the handle of an exi.sti.ng PS already
associ.ated wi.th a DC for the window then thl.s exl.stl.ng PS l.s used for the
p a 1. n t .

#defi.ne CHSTRR "repai.nt wi.ndow text"


#defi.ne NCHRSR (LONG)(si.zeof(CHSTRR)-1)

HPS hpspai.nt /* PS handle


RECTL rcl Rect /* rectangle
B00L fRet = FALSE /* B00L return code
P0INTL ptlcoord /* coordi.nate point

/* begl'n pal.nt
hpspai.nt = Wl.nBegi.npal.nt( hwnd /* -wi.ndow handle
hps /* -ps handle (may be NULL)
&rclRect /* -returned boundl.ng rectangle
in

l.f (hpspai.nt != NULL) /* repai.nt wi.ndow


fRet = Wi.nFi.llRect( hpspai.nt /* -PS handle
. &rclRect /* -rectangle requl.rl.ng repal.nt
CLR_BACKGROUND /* -fl.11 color
in
ptlcoord.x = 100L;
ptlcoord.y = 100L:
1'f (fRet)
fRet = (B00L)Gpl.Charstrl.ngAt( hpspai.nt
&ptlcoord p 0 1' n t
NCHRSR characters
CHSTRR s t r 1' n 9
in

I.f (hpspai.nt != NULL) /* end pal`nt


fRet = Wl.nEndpal.nt(hpspal.nt) && fRet; /* -PS handle

return ( fRet ) :

Figure 2.7 I+ocesswmpaint Function.


Drawing Primitives and Attributes

ATTRIBUTES

Chapter 1 described how graphics drawing is accomplished using drawing attri-


bute functions (e.g., Gpisetcolor GpisetMix), and drawing primitives (e.g., GpiL-
ine, GpicharstringAt), where the drawing attribute functions control the drawing
attributes (e.g., color, mix) to be used and the drawing primitives specify the
output operation to be performed. It was also pointed out that the drawing
primitives and their attributes can be divided into five major groups. In the case
of attributes, these groups are called attribute bundles. Certain other non-bundle
attributes also exist.
Most attributes may be set to default or an explicit non-default value. The
attribute value used for drawing is then taken from one of two places, either the
default, or the normal bundle structure.

Bundle Attributes
Bundle attributes are those attributes that apply to a particular primitive type
according to the following five groups:
Characters and Text (CIIARBUNDLE);
Lines and Curves (LINEBUNDLE);
Filled Areas or Patterns (AREABUNDLE);
Markers (MARKERBUNDLE); and
Image and BitBlt pixel operations (IMAGEBUNDLE).

59
60 OS/2 PRESENTATION MANAGER GPI

Any combination of attributes for a particular bundle can be set to a specified or


default value and queried using:
GpisetAttrs; and
GpiQueryAttrs.
For GpisetAttrs, separate default and attribute mask parameters define which
attributes are modified and which of these are to be set to default value. For
GpiQueryAttrs, a mask parameter defines the attributes to be queried and a
returned value identifies which of these are curently set to default.
In addition, the color and mix attributes, which appear in multiple bundles, are
called global attributes. These can be set or queried for an individual bundle using
GpisetAttrs/GpiQueryAttrs as described above or can be set for all applicable
bundles simultaneously using:
Gpisetcolor;
GpisetMix;
GpisetBackcolor (not applicable to LINEBUNDLE); and
GpisetBackMix (not applicable to LINEBUNDLE).
The corresponding query functions return values from the CIIARBUNDLE and
are:
GpiQuerycolor;
GpiQueryMix;
GpiQueryBackcolor; and
GpiQueryBackMix.
Functions also exist to set and query each of the non-global bundle attributes
individually as listed below. These are really for convenience and provide no
additional function over and above GpisetAttrdyGpiQueryAttrs. For the
LINEBUNDLE these are:
GpisetLinewidth/GpiQueryLinewidth;
GpisetLinewidthGeom/GpiQueryLinewidthGeom;
SetLine'IbpdyGpiQueryLineType;
GpisetLineEnd/GpiQueryLineEnd; and
GpisetLineJoin/GpiQueryLineJoin.
For the CIIARBUNDLE these are:
Gpisetcharset/GpiQuerycharset;
GpisetcharModg/GpiQuerycharMode (i.e. , precision);
GpisetcharBokyGpiQuerycharBox (i.e., cell);
DRAWING PRIMITIVES AND AFTRIBUTES 61

GpisetcharAnglg/GpiQuerycharAngle;
Gpisetcharshear/GpiQuerycharshear; and
GpisetcharDirection/GpiQuerycharDirection.
For the AREABUNDIH these are:
Gpisetpattemset/GpiQuerypattermset;
Gpisetpattexp/GpiQuerypattem (i.e. , symbol); and
GpisetpattemRefpoinvGpiQuerypattermRefpoint.
For the MARKERBUNDLE these are:
GpisetMarkerset/GpiQueryMarkerset;
GpisetMarkel/GpiQueryMarker (i.e., symbol); and
GpisetMarkerBox/GpiQueryMarkerBox (i.e., cell).
All IMAGEBUNDLE attributes are global attributes and so the IMAGEBUNDLE
has no additional functions.
Note that although the `LinewidthGeom' LINEBUNDLE attribute is fully sup-
ported, currently (for IBM OSA Version 1.3 at least), the `Linewidth' attribute has
not been implemented for any device and can only be set to its initial default value
of 1.0.
The bundle attributes are described in detail with their corresponding drawing
primitive descriptions below.

Hen-Bundle Attributes
In addition to the bundle attributes described above, the following non-bundle
attributes exist:
CuITent Position;
Arc Parameters;
Viewing Limits;
Himitive Tag;
Model Thansform Matrix; and
Viewing 'Thansformi Matrix.
The set and query functions for these are:
GpiMovg/Gpisetcurrentposition/GpiQuerycurrentposition;
GpisetArcparamfy/GpiQueryArcparams;
GpisetviewingLimits/GpiQueryviewingLimits;
GpisetTag/GpiQueryTag;
62 0S/2 PRESENTATION MANAGER GPI

Gpi s etMo delThansformMatrir§/GpiQueryMo del'ThansformMatrix; and


GpisetviewhgivansformMatrixp^GpiQueryviewingivansformMatrix.
The model transfomi matrix drawing attribute is also updated by the segment
transformi matrix when the segment is drawn, or by the GpicallsegmentMatrix
instance transformi when the seglnent call is executed (see chapter 7).
The viewing transformi matrix attribute, unlike other attributes, is unique in
that it applies only to graphics segments (including non-retained segments). To
understand its use, it is necessary to distinguish between the different forms of
viewing transfo]rm matrix that may exist. These are held in the:
presentation space;
retained segments; and
drawing attributes.
Only the latter is a true drawing attribute.
The matrix held in the presentation space is set and queried using the
GpisetviewingThansformMatrix and GpiQueryviewingThansformMatrix func-
tions mentioned above. This matrix is not used directly as a drawing attribute, but
when Gpiopensegment is issued to open a graphics segment, it is used to con-
struct the segment viewing transform matrix for the new segment. This sets the
drawing attribute directly for the duration of the segment definition and drawing,
is stored in an internal prolog at the start of the new retained segment, or both,
depending on drawing mode @M_DRAW, DM RETAIN or DM DRAWANDRE-
TAIN). A viewing transform matrix stored in the intermal prol:g of a retained
segment is used to set the drawing attribute for the duration of the segment
whenever it is subsequently drawn (e.g., using GpiDrawchain). Viewing trans-
formi operation is illustrated in Figure 3-1.
When using Gpiopensegment to create a new unchained segment that is to be
a called (rather than a root) segment, the presentation space viewing transform
matrix value should first be reset to identity (see chapter 7).
Currently IBM OS# Version 1.3 provides no means of querying the viewing
transform matrix value of either a retained seglnent or the drawing attributes.
This significantly affects the usefulness of this function.

Attribute Mode and Athibute Popping

A Normal-PS contains a LIFO stack that holds the retu]m information for called
segments. This stack also allows the existing value of any of the above attributes
(except viewing limits and viewing transfo]rm matrix) to be automatically pushed
as a new value is set and restored later using Gpipop. This attribute pushing
occurs if the attribute mode is set to AM PRESERVE. Note that
GpisetcuITentposition allows the current positio= to be pushed whereas
GpiMove, which is otherwise identical, does not. The default (reset) value of
attribute mode is AM_NOPRESERVE. Attribute mode is set and queried using:
DRAwlNG PRIMiTlvES AND AFTRIBUTEs ee

RETAINED
SEGMENT

I)RAVING
ArmlBUThs

LI)roving attrlbut® vl®vlng tran8forB Detrlx la reBet at the


end of each root 3egp®nt for r®taln®d legp®nt dravlng and
by Gpicloses®gp®nt ( for codes "_I}RAW/"_DRAWANDRETAIN).

Figure 3.1 Viewing 'Thansform Matrix Operation.

GpisetAttrMode; and
GpiQueryAttrMode.
Attributes are restored (or popped) in the reverse order from which they were
pushed. Gpipop includes a count parameter specifying the number of attributes to
be popped. For attributes pushed (and set) using a single global attribute setting
function (e.g., Gpisetcolor), a count of one is sufficient to pop the global attribute
for all bundles. If, however, multiple attributes are pushed (and set) using a single
GpisetAttrs call, a count of more than one is required to pop all the attributes.
Altematively, the attributes may be popped by using Gpipop multiple times with
a smaller count. In this case the attributes are popped in the order in which they
appear in their attribute bundle (i.e., color attribute first).
Unpopped attributes in a chained (root) segment are automatically popped and
discarded at the end the segment during any of the GpiDraw or Gpicorrelate
functions. Unpopped attributes in a called segment are automatically popped and
restored on retu]m to the caller.

Default Atwibutes
The above primitive attribute setting functions allow all attributes to be set to either
a specified or default value. The default values are initialized to defined constant
64 0S/2 PRESENTATION MANAGER GPI

values, certain of which are device dependent, or can be set to application defined
values. The initial default values are listed in the IBM OSA Hogramming Guide.
Default attributes are set to application defined values and queried using:
GpisetDefAttrs/GpiQueryDefAttrs;
GpisetDefArcparamdyGpiQueryDefArcparams;
GpisetDeITag/GpiQueryDeITag; and
GpisetDefviewingLimits/GpiQueryDefviewingLimits.
Unlike the other attribute setting functions described in this chapter, default
attributes are PS environment attributes and, therefore, should not be varied
during drawing.

Attribute Ouery[ng
Functions described earlier enable any drawing attribute value (except viewing
transform matrix) to be queried. It is, however, invalid to attempt to query drawing
attributes under either of the following conditions:
1. When a PS is associated with a DC of type OD_METAFILE_NOQU-
ERY.
2. When an open segment is being updated or edited without being
drawn (i.e., actual drawing mode is RETAIN).
Drawing attributes can be queried but are in an undefined state after any of the
following operations:
GpiDrawsegment;
GpiDrawFrom;
GpiDrawchain;
Gpicorrelatesegment;
GpicoITelateFrom;
Gpicorrelatechain;
Gpicallsegment;
Gpiopensegment (if AITR FASTCIIAIN = ATrR OFF for the
segment); and
Gpiclosesegment.

Attribute Resetting
Drawing attributes are reset to default value by any of the following:
• Any `set attribute' function specifying default value (e.g., GpisetMix
FM_DEFAUIJT).
DRAWING PRIMITIVES AND AFTRIBUTES 65

• GpisetAttrs with a flag set in both the attributes and defaults mask.
• GpiResetps.
• Gpisetps (with PS_NORESET option not specified).
• GpiplayMetaFile (with RES_RESET option specified).
• GpiAssociate.
• Gpiopensegment (in mode DM DRAW or DM DRAWANDRETAIN
ifATI`R_FASTCHAIN=ATI`R_6FF).
• At the start of any root segment during any of the following opera-
tions if ATrR_FASTCHAIN = AITR_OFF for the segment:
Gpicorrelatechain;
GpicoITelateFrom;
Gpicorrelatesegment;
GpiDrawchain;
GpiDrawFrom; and
GpiDrawsegment.
Default drawing attributes are reset to their initial default value by:
• GpisetDefAttrs with a flag set in both Attributes and Defaults Mask.
• GpiResetps (option: GRES_SEGMENTS or GRES_ALL).
• Gpisetps (with PS_NORESET option not specified).
• GpiplayMetaFile (with RES_RESET option specified).

TEXT AHD CHARACTER FUHCTIOHS

Character Bundle Attributes

Characters are drawn using the CHARBUNDLE (character bundle) attributes.


The CHARBUNDLE attributes and flags ®arenthesized) are as follows:

IColor (CBB_COLOR)

This specifies the character color.

lBackcolor (CBB_BACK_COLOR)

This specifies the character box (or cell) background color.

usMixMode (CBB_MIX_MODE)

This specifies the character mix mode.


66 OS/2 PRESENTATION MANAGER GPI

usBackMixMode (CBB_BACK_MIX_MODE)

This specifies the character box (or cell) background mix mode.

usset (CBB_SET)
This defines the id of the font to be used for drawing characters. A value of zero
(LCID_DEFAULT) specified with Gpisetcharset sets the current character set to
default. A value of zero specified with GpisetAttrs or GpisetDefAttrs sets the
current or default character set back to the initial default set.

usprecision (CBB_MODE)

This defines the character mode or precision with which characters should be
drawn in terms of which character bundie attributes must be honored, which are
optional, and whether or not the font must be an outline font. This is specified as
one of:
CM_MODEl specifies that character box, angle, shear, and direc-
tion attributes may be ignored for raster font characters. All other
character attributes are fully honored. CM_MODE 1 raster charac-
ters are always drawn as normal left to right text.
CM_MODE2 specifies that character box, angle, shear, and direc-
tion attributes are used to determine the position of each raster font
character only. Orientation and size are unaffected by these attri-
butes and all other character attributes are fully honored.
CM_MODE3 specifies that characters must be drawn using an
outline font. Raster font characters are invalid in this mode. For out-
line characters, all attributes are fully honored regardless of mode.

sizfxcell (CBB_BOX)

This defines the character box or cell width and height in world coordinates. These
dimensions control the size of outline font characters (regardless of mode) and the
spacing of outline and CM_MODE2 raster font characters. For outline characters,
the lEmlnc and lEmHeight font metrics are set to the character box dimensions
with other width and height metrics (e.g., lAvecharwidth and lMaxBaselineExt)
scaled in the same proportion. The ratio CharacterwidthAEmlnc is normally
constant for a given character of a particular font or, for a non-proportional font,
for all characters of the font (i.e., lAvecharwidthtlEmlnc). The horizontal charac-
ter spacing of outline and CM_MODE2 raster characters can therefore be deter-
mined by CharacterBox. cx * CharacterwidthAEmlnc.
One or both character box dimensions can be specified as zero causing outline
characters to collapse into line or a single point.
Character box dimensions may also be negative causing outline characters to be
drawn reflected and the character spacing of both outline and CM_MODE2 raster
characters to be reversed.
For ideally proportioned (i.e., as designed) outline characters, the character box
DRAwlNG PRIMITlvES AND AFTRiBUTEs 6rf

widththeight ratio should match the metrics ratio sXDeviceRes/sYDeviceRes. This


is normally one for outline fonts as these are generally defined in a 1000xl000
square space. An exception is a device outline font such as a plotter font.
For outline font characters, the two rectangles sX/YDeviceRes and character box
define a transformi from font definition space to world coordinates. This extra
transform. sits above the model transformi matrix illustrated in Figure 7-2.
Note that even when drawing using the default font and character mode
CM_MODE1,unlesstheapplicationhasverifiedthatthefontreallyisarasterfont,
itisstillnecessarytosetthecharacterboxattribute.Itmustbesettoavalueinworld
coordinates that will produce coITectly sized outline characters for the current
transforms.Thisisessentialtoensurethattheapplicationwilloperatesuccessfully
withanycurrentandfuturedevicesthatprovideanoutlinefontastheirdefault.Note
alsothatanoutlinefontmaybereturmedfromGpicreateljogFontduetoarasterfont
match failure.Thiswillalsorequirethatthecharacterboxattributebesetcomectly.
Examples of the character box attribute are illustrated in Figure 3-2.

ptlAngle (CBB_ANGLE)
This defines the character angle as the coordinates of a point that specifies the
angle of the baseline of a character string. For CM_MODEl raster characters,
character angle is ignored. For CM_MODE2 raster characters, character angle
affects only the position of each character but not its orientation. For CM_MODE3,
the cuITent font must be an outline font. For outline characters in all modes,
character angle affects both position and orientation of characters. Characters are
drawn perpendicular to the rotated baseline. A character angle value of (0,0) is
interpreted as `set to default.' The initial default value of character angle is (1,0)
representing a character angle of zero that positions characters left to right along
the x axis. Examples of the character angle attribute are illustrated in Figure 3-3.

ritbiw xod evitJs8ffl

REtline Font

I MMODE2Ragter

Figure 3.2 Character Box Attribute ®ositive and negative values).


68 OS/2 PRESENTATION MANAGER GPI

Figure 3.3 Character Angle Attribute.

ptlshear (CBB_SHEAR)
This defines the character shear as the coordinates of a point that specifies a shear
angle. A non-zero shear angle gives the character an oblique or italicized appear-
ance. A character shear value of (0,0) is interpreted as `set to default.' The initial
default value of character shear is (0,1) giving upright characters. If the values are
both positive or both negative, the tops of the characters slope to the right. If the
signs are opposite, they slope to the left. An example of character shear is
illustrated in Figure 3-4.

Figure 3.4 Character Shear Attribute.


DRAWING PRIMITIVES AND ATTRIBUTES 69

usDirection (CBB_DIRECTION)

This specifies the character direction as one of:


CHDIRN_REFTRIGHT (left to right);

CHDIRN_TOPBOTI`OM (top to bottom);

CIIDIRN_RIGHTLEFT (right to left);

CHDIRN_BOTroMTOP ®ottom to top);

Examples of the character direction attribute are illustrated in Figure 3-5.

TFELTHGIR NRIDHC CHDIRN LEFTRIGHT

Figure 3.5 Character Direction Attribute.


10 0S/2 PRESENTATION MANAGER GPI

Character String Primit]ves


Character strings can be drawn using any of the following functions:
Gpicharstring;
GpicharstringAt;
Gpicharstringpos; or
GpicharstringposAt.
Gpicharstring and GpicharstringAt are identical except the latter draws from a
specified point rather than the cuITent position. Likewise, Gpicharstringpos and
GpicharstringposAt are identical except GpicharstringposAt draws from a spec-
ified point rather than the cument position.
Gpicharstringpos and GpicharstringposAt offer the following additional op-
tions over and above Gpicharstring and GpicharstringAt:
CHS_OPAQUE specifies that the rectangle parameter defines a
background rectangle that should be filled using character back-
ground color and overpaint mix attributes.
CHS_VECTOR specifies that the increment vector parameter
should be used to define the character spacing in world coordinates.
This can be used by an application to precisely control the position-
ing of each individual character. For example, it can be used to pro-
vide keming or to draw proportional font characters with fixed pitch.
CHS_LEAVEPOS specifies that the cuITent position should not be
updated by this function. Otherwise, the function (like Gpicharstr-
ing/GpicharstringAt) will update the current position to the posi-
tion at the end of the string where the next character would be
draun.
CHS_CLIP specifies that the rectangle parameter provided should
be used for clipping the characters output by this function.
Additional functions are provided to process the character string in an identical
manner to Gpicharstringpos and GpicharstringposAt but, instead of drawing
the characters, return the coordinate positions at which each character would be
draun. These are:
GpiQuerycharstringpos; and
GpiQuerycharstringposAt.

Char_Extra and Break_Extra Spacing


Some devices (e.g., PostscriptTh) allow the spacing between each character to be
increased by an additional amount specified in world coordinates using
DevEscapeoEVESC_CHAR_EXTRA. This char_extra spacing is in addition to
DRAWING PRIMITIVES AND AFTRIBUTES 11

any width vector ®rovided with Gpicharstringpos) and any kerming adjustment.
The char_extra spacing is initialized to zero when a DC is created.
Such devices also allow the width of each break (or space) character to be
increased by an additional amount specified in world coordinates using
DevEscapeoEVESC_BREAK_EXTRA. The break_extra spacing is in addition to
the char_extra spacing. The break_extra spacing is initialized to zero when a DC
is created.
The codepoint of the space or break character of a font is returned by
GpiQueryFonts as one of the metrics.

L"E AND CURVE FIJIICTI0HS

Line Bundle Attr]butes

Lines and arcs are drawn using the LINEBUNDLE (line bundle) attributes. In the
case of arcs (GpipointArc, GpipartialArc, and GpiFullArc), the ARCPARAMS (arc
parameters) are also used. In addition, the AREABUNDLE (area bundle) attri-
butes are used when either of the fill options are specified with GpiFulldrc or
GpiBox. The LINEBUNDLE attributes and flags ®arenthesized) are as follows:

IColor (LBB_COLOR)

This specifies the line color.

usMixMode (LBB_MIX_MODE)

This specifies the line mix mode.

fxwidth (LBB_WIDTH)

This specifies the cosmetic line width as a multiplier consisting of an integer and
fractional part. As a minimum, if the cosmetic line width is greater than 1.0, this
should produce double width lines; otherwise, the lines should be single width. In
practice, however, values other than 1.0 are unsupported by IBM OSA Version 1.3.
Cosmetic line width is of type FIXED (see chapter 1).

IGeomwidth (LBB_GEOM_WIDTH)

This specifies the geometric line width. This is used exclusively with paths (see
below).

usType (LBB_TYPE)

This specifies the line style, for example, solid, dotted. (see Figure 3no).
-pr
12 0S/2 PRESENTATION MANAGER GPI

IINErYPE_SHORmASH

LINErmE.PASIIDOT

IJNEITYPEPOUBIEDOT

IniErypE+ONGDASH

IINErTPEPASIIDoUBIrooT

I-_SOLD
I.INEIT¥PEAILTmNATE

IINErypEPTvlslBu
Figure 3.6 Standard Line Types.

usEnd (LBB_END)

This specifies the line end attribute. This is used exclusively with paths (see
below).

usJoin (LBB_JOIN)

This specifies the line ].oin attribute. This is used exclusively with paths (see
below).

Line and Curve Primitive Functions

The line and curve primitive functions are described below.

GpiLine

This draws a single straight line from the current position to a specified point and
updates the current position.

GpipolyLine

Thisdrawsasuccessionofconnectedstraightlinesfromthecurrentpositionthrough
a series of specified points. The current position is updated to the last point in the
series. Points may be coincident and the number of specified points can be zero, in
which case the function is a no-op. This function is a superset of that of GpiLine.
DRAWING PRIMITIVES AND AFTRIBUTES 13

GpipolyFillet

This draws a succession of fillets starting from the current position and ending at
the last in a series of specified points. The fillets pass through the mid-point of the
second and all subsequent imaginary straight lines up to and including, the last
but one of a series connecting the curent position and all adjacent specified points.
The fillets are tangential to the imaginary lines at the curent position, the last
point in the series, and all mid-points through which they pass. If only two points,
including current position, are specified, then the curve is tangential at the current
position and second point. The current position is updated to the last point in the
series. Points may be coincident and the number of specified points can be zero, in
which case the function is a no-op. Examples of the two cases of GpipolyFillet are
illustrated in Figure 3-7.

GpipolyFilletsharp

This draws a succession of fillets starting from the current position, passing
through alternate points and ending at the last of a series of 2*n specified points
(where n is the number of fillets). The fillets are tangential to imaginary straight
lines connecting adjacent points at each point through which they pass. The
alternate points through which fillets do not pass are control points used with a
sharpness value from a sharpness array supplied as a separate parameter. The
current position is updated to the last point in the series. Points may be coincident
and the number of specified points can be zero, in which case the function is a
no-op. GpipolyFilletsharp is illustrated in Figure 3-7.
Each sharpness value is a ratio controlling the shaxpness of one fillet (see Figure
3no) where:
shaxpness > 1.0 defines a hyperbola;
sharpness = 1.0 defines a parabola; and
sharpness < 1.0 defines an ellipse.

Gpipolyspline

This draws a succession of Bezier splines starting from the current position and
passing through every third point of a series of 3*n specified points (where n is the
number of splines). The pairs of intervening points are control points. The current
position is updated to the last point in the series. Points may be coincident and the
number of specified points can be zero, in which case the function is a no-op.
Gpipolyspline is illustrated in Figure 3-7.

GpiFullArc

This draws a complete circular or elliptical arc with its center at the curent
position.Thearcparameters(seebelow)togetherwithaspecifiedmultiplier(S255)
control the shape and size of the arc. The options allow the outline @RO_OUT-
74 OS/2 PRESENTATION MANAGER GPI

I-------I

GpipolyFfllet example 2 (only 2 points ph]s cunent position provided)

Figure 3.7 Gpipolyspline, GpipolyFilletsharp, and GpipolyFillet.

LINE), the interior @RO_FILL), or both @RO_OUTLINEFILL) to be drawn. The


interior, if drawn, is filled using the AREABUNDIE attributes. The cument
position is not affected by this function. The multiplier is of type FIXED (see
chapter 1).
DRAWINC; PRIMITIVES AND AFTRIBUTES 15

D
SharpBees I DEpe

Figure 3.8 GpipolyFilletsharp Sharpness.

GpipartialArc
This draws a straight line from the current position to the start point of the arc
followed by a circular or elliptical arc with its center at a specified point. The arc
parameters (see below), together with a specified multiplier (S255), control the the
shape and size of the arc. The star and end points of the arc are defined by a
specified positive start and sweep angle (in degrees) measured counterclockwise
using the unit circle before application of the arc parameters (i.e., the specified
angles will be modified by the arc parameters if these do not define a circular arc).
The start angle is measured from the x-axis. The current position is updated to the
end point of the arc. GpipartialArc can be used to draw a pie slice (see the function
Drawpieslice in Figure 3-9) or a closed figure bounded by a chord and an arc (see
the function DrawchordAndArcFigure in Figure 3-10). The multiplier and start
and sweep angles are of type FIXED (see chapter 1).

GpipointArc

This draws an arc through three points starting from the current position. The arc
parameters (see below) control the the shape of the arc. The current position is
updated to the end point of the arc.

GpiBOx

This draws a box with diagonally opposite comers at the current position and a
specified point. The comers of the box may be optionally rounded with a quarter
ellipse defined by the rounding controls. If either or both rounding controls are
zero, then no rounding occurs. If both are non-zero, then they define the horizontal
and vertical full axes of the ellipse to be used for rounding. If they are non-zero
and equal, then the corners are rounded using a quarter circle. The options allow
the outline @RO_OUTLINE), the interior @RO_FIIIL), or both @RO OUT-
LINEFILL) to be drawn. The interior, if drawn, is filled using the AREABtinLE
attributes. The current position is not affected by this function.
76 OS/2 PRESENTATION MANAGER GPI

pl.esll.ce.c */
OL Drawpi.esli.ce (HPS hps)

Draw pi.e sli.ce usi.ng the current arc parameters. */


*/
1.nputs: hps PS handle */
*/

#defi.ne MULTIPLIER Ox00028000 L


#defi.ne STARTANGLE 0x00300000 L
#defi.ne SWEEPANGLE 0x00400000 L

P0INTL ptlposn /* center pol.nt


B00L fRet /* B00L return code
ARCPARAMS arcpparms /* arc parameters

arcpparms.1P = 500L;
arcpparms.1Q = 500L;
arcpparms.IR = OL;
arcpparms.1S = OL: /* set arc parameters
fRet = Gpl.SetArcparams( hps /* -PS handle
&arcpparms /* -arc parameters
in

ptlposn.x = 3000L:
ptlposn.y = 1000L;
1' f ( f R e t ) /* set center posi.ti.on
fRet = Gpl.Setcurrentpositl.on( hps /* -PS handle
&ptlposn /* -coordl.nate pol.nt
in

l`f (fRet) /* draw radl.us and arc


fRet = (B00L)Gpi.Partl.alArc( hps /* -PS handle
&ptlposn /* -center posi.ti.on
MULTIPLIER /* -multl.pll'er
STARTANGLE /* -start angle
SWEEPANGLE /* -sweep angle
in

l'f (fRet) /* draw radi.us back to center


fRet = (B00L)Gpi.L1.ne( hps /* -PS handle
&ptlposn /* -coordl.nate pol.nt
n
return (fRet);
)

Figure 3.9 DrawFieslice Function.

Gpioutlinepath

This draws a line describing the outline of a path (see below).

Arc Parameters
The arc parameters p, q, r, and s define a transform matrix that maps a unit circle
to the required ellipse, thus:

x' = p*x + r*y

y' = s*x + q*y


DRAwlNG PRIMITlvES AND AFTRIBUTEs n

charcfl.g.c */
OL DrawchordAndArcFl.gure(HPS hps)

Draw closed fi.gure bounded by a chord and an arc usl.ng the current arc
pa rameters .

i.nputs: hps PS handle

!idef ] ne MULTIPLIER Ox00028000 L


!ideflne STARTANGLE 0x00300000 L
!Idef i ne SWEEPANGLE 0x00400000 L
!idef]ne ENDANGLE (STARTANGLE + SWEEPANGLE)

P0INTL ptl Posn /* center poi.nt


B00L fRet /* B00L return code
ARCPARAMS arcpparms /* arc parameters

arcpparms.1P = 500L:
arcpparms.10 = 500L;
arcpparms.IR = OL:
arcpparms.1S = OL; /* set arc parameters */
fRet = Gpi.SetArcparams( hps /* -PS handle */
&arcpparms /* -arc parameters */
in

1'f (fRet) /* set ll.ne type l.nvl.sl.ble */


fRet = Gpi.SetLi.neType( hps /* -PS handle */
LINETYPE_INVISIBLE /* -11`ne type */
n
Posn.x = 3000L:
Posn . -1000L;
(fRet end pol'nt
fRet = (B00L)Gpi.Parti.alArc( hps
&ptlposn p 0 ,' n t
. MULTIPLIER
ENDANGLE
OL (zero)
in

l'f (fRet) /* set ll.ne type vl.si.ble


fRet = (B00L)Gpl.SetLl.neType( hps /* -PS handle
LINETYPE_SOLID /* -li.ne type
n
l'f (fRet) /* draw chord and arc
fRet = (B00L)Gpi.Parti.alArc( hps /* -PS handle
&ptlposn /* -coordi.nate poi.nt
MULTIPLIER /* -multl'pll.er
STARTANGLE /* -start angle
SWEEPANGLE /* -sweep angle
);

return (fRet);

Figure 3.10 DrawchordAndArcFigure Function.

Forgreatestaccuracy,thetransformshouldbeorthogonal(i.e.,suchthatp*r+s*q
= 0). Consider first a unit circle centered at the origin. This can be napped to the
required ellipse with ma].or and minor axes of 2a and 2b along the x and y axis
respectively by setting p=a, q=b, r=O and s=0.
78 OS/2 PRESENTATION MANAGER GPI

i.e. x, = a*x

y' = b*y

This ellipse then can be rotated counterclockwise through R degrees by modifying


these previous values, thus: p=acosR, q=bcosR, r=-bsinR and s=asinR.

i.e. x' = acosR*x -bsinR*y

y' = asinR*x + bcosr*y

An unrotated and a rotated ellipse are illustrated in Figure 3-11.


As arc parameters are specified as integers, a and b should be sufficiently large
to scale the values of CosR and SinR such that precision is not lost by discarding
the fractional part of the result. The overall size of the ellipse can then be
controlled by scaling down using the arc multiplier parameter (with GpiFullArc
and Gpipartialdrc).

(ro ®JS)

p = 1500, q = 7sO, I = 0, 8 = 0

p = 1500 Cbs 30, q = 750 Cfo8 30, I = -750 Sin 30, a = 1500 Sin 30
Figure 3.11 Arc Parameters.
DRAWING PRIMITIVES AND AFTRIBUTES 19

Gp[Sctpel and Gploucrypel

Gpisetpel is similar to the BitBlt and Gpilmage functions except it uses the
LINEBUNDLE rather than the IMAGEBUNDIE attributes. It sets the pel at the
specified position using the LINEBUNDLE color and mix attributes. Gpisetpel is
never stored in a retained graphics segment but is always output directly to the
device, regardless of drawing mode. Note also that Gpisetpel does not conform to
the MetaFile interchange architecture and should not therefore be used when
creating a MetaFile for interchange with other products (see chapter 11).
GpiQuerypel is the reverse of Gpisetpel and returns the color index or RGB
value (according to the logical color table mode) of the pel at the specified position.
If the pel is not visible, because for example it is overlayed by another window, an
error is returned.

AREA DRAWING FUHCTIOMS

Area Bundle Attributes

Areas are drawn using the AREABUNDLE (area bundle) attributes. The
AREABUNDLE attributes and flags ®arenthesized) are as follows:

lcolor (ABB_COLOR)

This specifies the area fill pattern foreground color.

IBackcolor (ABB_BACK_COLOR)

This specifies the area fill pattern background color.

usMixMode (ABB_MIX_MODE)

This specifies the area fill pattern foreground mix mode.

usBackMixMode (ABB_BACK_MIX_MODE)

This specifies the area fill pattern background mix mode.

usset (ABB_SET)

This defines the id of the pattern set, logical font, or bitmap to be used for the area
fill. An area fill operation can use a pattern from the standard pattern set, a
particular character from a logical font, or a bitmap tagged with a set id (see
chapter 4). A value of LCID_DEFAUIJT (zero) specifies default, which will initially
reference the standard pattern set illustrated in Figure 3-12.
80 OS/2 PRESENTATION MANAGER GPI

= PATSYM_IIALFTORE

PATSYM_DENSE8 gife;i¥;ii¥; PATS"_SOLID

PATSYM DENSE7
H PATSYM_NOSIIADE & PATSYM_BLANK

i.. .££..RE
PATSYM_DENSE6
= PATS"_DIAG4

:=: PATSYM_DENSE5
RE
PATS"_DIAG3

;
PATSYM_DENSE4
= PATSYM_DIAG2

:::;:::::::::::::;
PATSYM_DENSE3
Zi PATS"_DIAG1

;:;:;;::;:::::;:::
PATSYM_DENSE2
Ei PATSYM_HORE

E PATSYM_DENSE1
111111111
PATS"_VERT

Figure 3.12 Standard Pattern Set.

ussymbol (ABB_SYMBOL)

This defines the pattern within the standard pattern set or the character codepoint
within the logical font specified by the usset attribute. If the current pattern set
is a bitmap then the ussymbol attribute is ignored.

ptlRefpoint (ABB_REF_POINT)

This defines the pattern origin in world coordinates. Its initial default value is
(0,0). The pattern origin can be outside the area to be filled.
This attribute is intended to avoid area boundary discontinuities that might
occur when part of a picture is scrolled using GpiBitBlt and the remainder is
redrawn. The scroll distance should be converted from device to world coordinates
using Gpiconverd and used to adjust the pattern origin before redrawing the
picture. Unfortunately, transform rounding errors make it impossible to always
guarantee complete freedom from all discontinuities.
DRAWING PRIMITIVES AND AFTRIBUTES 81

Area Primitiv®s

An area is drawn using the following sequence of functions, as illustrated by the


function DrawArea in chapter 1.

GpiBeginArea

GPI drawing calls defining one or more closed figures.

GpiEndArea

All boundaries are inclusive and fo]rm part of the filled area.
If a figure inside an area bracket is not closed, GpiEndArea generates an
automatic closure line from the end to the staid of the figure.
Only certain functions are valid within an area. These are basically functions
that produce lines (including outline fonts) and certain attribute setting functions
(see the IBM OSA Hogramming Reference for a complete list of valid functions).
GpiBeginArea provides the following options :
BA_BOUNDARYZBA_NOBOUNDARY specifies whether or not
boundary lines are drawn in addition to the filled interior.
BA_ALTERNATE/BA_WINDING specifies whether the fill should
be performed using alternate or winding mode. This option is signifi-
cant for areas defined by multiple overlapping figures. In alternate
mode, a figure segment is filled if, counting from infinity to a point
in the segment, the number of figure boundary line crossings is odd.
Figure segments for which this number is even are not filled.
In winding mode, the direction of the boundary lines is signifi-
cant. Figure boundary lines drawn in one direction (e.g. clockwise)
can be considered to have a weight of +1 and those in the opposite di-
rection a weight of -1. A figure segment is filled if, counting from in-
finity to a point in the segment, the net weight of the figure bound-
any line crossings is non-zero. Figure segments for which the net
weight is zero are not filled.
An area consisting of a six-pointed star defined by two triangles
drawn using both BA_ALTERNATE and BA WINDING mode is
illustrated in Figure 3-13.
Areas can also be drawn by defining a path and issuing GpiFillpath (see below).
Areas are implemented intermally by the system using path functions. Note that
for IBM OSA Version 1.3 at least, there is an internal limit of 64K on the maximum.
size of a path and it is not possible to predict with any certainty when this limit
will be reached. When reached, an error is returned and the error code
PMERR_PATH_LIMIT_EXCEEDED is logged.
82 0S/2 PRESENTATION MANAGER GPI

BA.AIJTmNATE I]rode BALWINI)ING dxxle

Figure 3.13 Areas Drawn using BA_AIJTEENATE and BA_WINDING mode.

MARKER FUMOTI0MS

Markers are typically used for displaying points on a graph and are similar to
characters except for the way in which they are positioned. Whereas characters
are positioned by a reference point near the bottom left corner of the first character
of a string, with each subsequent character positioned relative to that preceding
it, markers are individually positioned by their marker box center.
The system provides a standard marker set as illustrated in Figure 3-14. Altema-
tively a raster or outline font character can be used as a marker symbol. However,
a font character used as a marker will be imperfectly positioned if its sylnbol
definition is not positioned centrally within its character box.

Marker Bundle Adributes

Markers are drawn using the MARKERBUNDLE (marker bundle) attributes. The
MARKERBUNDLE attributes and flags ®arenthesized) are as follows:

IColor (MBB_COLOR)

This specifies the marker color.

lBackcolor (MBB_BACK_COLOR)

This specifies the marker box (or cell) background color.

usMixMode (MBB_MIX_MODE)

This specifies the marker mix mode.


DRAWING PRIMITIVES AND AFTRIBUTES 83

X MARKSYM_CROSS

+ M-"LPLUS
a MARKSYM_DIAMOND

I MARE"_SQUARE

* MARKsyM_sEDOINrsTAR

* MARKsyM_EIGlrlrolNTSTAR

• MARKSYM_SOLDDIAMOND

I MARKSYELSOLDSQUARE

• MAus"_COT
0 MARKsyM_sMAIImaE

MARKS"_BLANI
Figure 3.14 Standard Marker Set

usBackMixMode (MBB_BACK_MIX_MODE)

This specifies the marker box (or cell) background mix mode.

usset (MBB_SET)

This defines the id of the marker set or font to be used for drawing markers. A
value of zero qcID_DEFAULT) specified with GpisetMarkerset sets the current
markersettodefault.AvalueofzerospecifiedwithGpisetAttrsorGpisetDefAttrs
sets the current or default marker set back to the standard marker set (i.e., the
initial default).

ussymbol (MBB_SYMBOL)

This specifies the codepoint of the marker symbol within the current marker set
(or character within the font) to be used for drawing markers.

sizfxcell (MBB_BOX)

This specifies the marker box width and height in world coordinates. These control
thesizeofmarkersdrawnusingoutlinefontcharacters.Formarkersdrawnusing
84 0S/2 PRESENTATION MANAC;ER GPI

the system (raster) marker set or raster font characters, the marker box attribute
is ignored. Although the marker box dimensions are of type FIXED for consistency
with the character box attribute, for marker box dimensions the fractional part
should always be specified as zero. This is because the `set marker set' order stored
in MetaFiles and retained segments is unable to support a fractional part and, in
such situations, the fractional part will be discarded.

Marker Pr]m]t[vcs
Markers are drawn using the GpiMarker and GpipolyMarker functions described
below.

GpiMarker

This draws a marker at a specified position and updates the current position.

GpipolyMarker

This draws a series of markers at specified positions and updates the current
position to that of the last marker. A count of zero is valid and in which case the
function will be treated as a no-op. This provides a superset of the function
provided by GpiMarker.

IMAGE AMP BITBLT FUHCTIOHS

Image Bundle Attributes


A GPI image is a rectangular array of monochrome (1 bit per pel) pixel data. GPI
images are drawn using the IMAGEBUNDLE (image bundle) attributes.
BitBlt operations provide an alternative, and improved, method of performing
image operations. The IMAGEBUNDLE foreground and background color attri-
butes are also used in certain BitBlt operations involving monochrome bitmaps
(see below).
These functions return an error if issued to a device such as a plotter that does
not support raster operations. See chapter 5 for BitBlt programming examples and
a description of bitmaps.
The IMAGEBUNDLE attributes and flags ®arenthesized) are as follows:

IColor (lBB_COLOR)

This specifies the image foreground color.

IBackcolor (IBB_BACK_COLOR)

This specifies the image background color.


DRAWING PRIMITIVES AND AFTRIBUTES 85

usMixMode (IBB_MIX_MODE)

This specifies the image foreground mix mode.

usBackMixMode (IBB_BACK_MIX_MODE)

This specifies the image background mix mode.

Image and BitBIt Draw[ng Pr]mitives

The image and BitBlt drawing functions are described below.

Gpilmage

This draws a rectangular pixel image with its top left origin at the current
position. The image data consists of a single plane of data with one bit per pel
in application memory. The data is arranged as an array of bytes, where the first
byte represents the first eight pixels (of the top row) to be drawn from the
current position, with the most significant bit of each byte representing the
leftmost pel. The bits in the final byte of each row are padded, as necessary, to
a byte boundary. The image is drawn with `one' bits displayed using the IM-
AGEBUNDLE foreground mix and color and `zero' bits the background mix and
color.
Typically, the three separate planes of an RGB image would be drawn in turn
with a foreground mix of FM_OR, background mix of BM_LEAVEALONE, and
foreground color of CLR_RED, CLR_GREEN, and CLR_BLUE respectively.
The Gpilmage function is provided primarily for reasons of compatibility with
earlier products. The BitBlt functions are generally considered to be more suitable
for the ma].ority of new applications.

GpiBitBit

This function enables the rapid transfer of a rectangular array of pixel data
between a source and target pixel device or bitmap. The source and target of a
GpiBitBlt operation can include any of the following combinations:

a bitmap and device;


a device and bitmap;
the sane device;
the sane bitmap; and
different bitmaps.

Bitmaps are device dependent ob].ects and both the source and target of any BitBlt
operation must be `owned' by the same device (e.g., for the display, source and
86 OS/2 PRESENTATION MANAGER GPI

target must be either a display window or a bitmap owned by the display device).
Bitmap ownership is established at creation time by the PS (and associated DC)
specified with GpicreateBitmap and GpilloadBitmap.
It is possible to transfer bitmap ownership from one device to another using
GpisetBitmap to deselect the bitmap from the Psroc for the old device (if selected)
and select it to a Psroc for the new device (see chapter 5).
A bitmap can be created in any one of the four standard form.ats (i.e., a single
plane with 1, 4, 8, or 24 bits per pel) or may be in a device internal format that is
not one of the standard formats. The format with a single plane and 1-bit per pel
is referred to as a monochrome bitmap.
When using GpiBitBlt with a color source and monochrome target or with a
monochrome source and output device surface or color target, color conversion
occurs. The rules of color conversion are as follows:

Monochrome source to monochrome bitmap target-No color con-


version is performed, the IMAGEBUNDLE attributes are not used.
Monochrome bitmap source to monochrome target device sur-
face-Color conversion is performed using the target IMAGEBUN-
DLE background and foreground colors for the source `0' and `1'
bits respectively. Note that this was not always the case and some
older drivers may not provide this conversion. This change was in-
troduced to provide consistency between BitBlt operations per-
formed on a color display and those performed on a monochrome
printer.
Monochrome source to color target-Color conversion is per-
formed using the target IMAGEBUNDLE background and fore-
ground colors for the source `0' and `1' bits respectively.
Color source to monochrome target-Color conversion is per-
formed using the source IMAGEBUNDLE background color to deter-
mine which source bits are background (all other bits are assumed
to be foreground) and the target IMAGEBUNDLE foreground and
background colors for the source foreground and background bits
thus obtained.
Monochrome patterm to color target (see belowLColor conversion
is performed using the target AREABUNDLE background and fore-
ground colors for the pattern `0' and `1' bits respectively.
Color source to color target-Color conversion is not performed,
the IMAGEBUNDLE attributes are not used.

Note that if part of the source is unavailable because, for example, it is overlayed
by another window on the display screen, then this part of the target is undefined
and no eITor is returned by GpiBitBlt.
The GpiBitBlt parameters are as follows:
DRAWING PRIMITIVES AND AFTRIBUTES &J

LONG GpiBitBlt( Iips hpsTarget


ITS hpssource
LONG ICount
PPOINTL aptlpoints
' LONG IRop
ULONG floptious
);

hpsTarget and hpssource These identify BitBlt source and target presentation
spaces. If the Rop mix value does not require a source (e.g., ROP_PATCOPY or
ROP_ZERO) then the source PS may be specified as NULL. Source or target
may be associated with a display window DC or an OD_DIRECT DC for any
raster device. Where the source or target is a bitmap, the bitmap must be
selected into an OD_MEMORY DC associated with the specified PS. The DC
associated with the target PS can also be a DC of type OD_QUEUED,
OD_METAFILE, or OD_METAFILE_NOQUERY. A MetaFile containing a re-
corded GpiBitBlt operation will not conform to the MetaFile interchange archi-
tecture (see chapter 11).

ICountand aptlpoints These identify an aITay of 2, 3, or 4 coordinate points (in


device coordinates) providing a target and optional source rectangle. If the Rop mix
value does not require a source (e.g., ROP_PATCOPY or ROP_ZERO) then only
two points are required. If three coordinates are supplied then source and target
are assumed to be the same size and if all four coordinates are supplied, then the
source and target may be different sizes to allow stretching or compression of the
source bitmap data. As GpiBitBlt coordinates are specified as device coordinates,
they are unaffected by the GPI transforms.

IRop This specifies the Rop (raster operation) mix mode value and optionally
allows a monochrome pattern (defined by the AREABUNDLE) to be included in
addition to (or in place of) the source bitmap, providing a `three-way' BitBlt
operation.
The Rop code mix value is determined by constructing a truth table containing
all combinations of input Pattern Q?), Source (S), and Target Original Value (0) for
any pixel and specifying the New Target Value (D required for each combination.
The number thus obtained from the eight bits defining T provides the Rop code
value.
For example, the Rop code required to replace the target with pattern fore-
ground or background at each source pixel that is `1' (i.e., if S=`1', T=P) and to leave
the target unchanged at every source pixel that is `0' (i.e., if S=`0' T=O) is OxOOE2L
as illustrated below.
88 OS/2 PRESENTATION MANAGER GPI

Pattern Source OriginalTarget NewTarget


(P) (S) (0) cO
0 00 0
0 01 1

0 10 0
0 11 0
1 00 0
1 01 1

1 10 1

1 11 1 (most
significant bit)
The system provides predefined symbolic constants for the following most fre-
quently used Rop mix values:
ROP SRCCOPY (OxOOCCL) T= S
ROP SRCPAINT (OxOOEEL) T=S I O
ROP SRCAND (OxOO88L) T= S&O
ROP SRCINVERT (Ox0066L) T= S ^ O
ROP SRCERASE (OxcO44L) T=S&~ O
ROP NOTSRCCOPY (OxcO33L) T= ~ O
ROP NOTSRCERASE (OxOOllL) T=~ S&~ O
ROP MERGECOPY (OxOOCOL) T=P&S
ROP MERGEPAINT (OxOOBBL) T=~S I O
ROP IIATCOPY (OxOOFOL) T= P
ROP PATPAINT (OxOOFBL) T=~S I P I O
ROP PATINIRT (OxcO5AL) T= O ^ P
ROP DSTIIVERT (OxcO55L) T= ~ O
ROP ZERO (OxOOOOL) T= 0
ROP ONE (OxOOFFL) T= 1
For determining the effect of the Rop code on a color target, the target must be
regarded as multiple planes, each of one bit per pel (rather than one plane with
multiple bits per pel), with each plane processed separately.
DRAWINC; PRIMITIVES AND AFTRIBUTES 89

floptions The options are applicable only to compression and control the appear-
ance at positions where pels are eliminated:
BBO_OR specifies that multiple eliminated pels are ORed with a
remaining pel (this ensures that when `0' is foreground, background
`1' pels are preserved).

BBO_AND specifies that multiple eliminated pels are ANDed


with a remaining pel (this ensures that when `1' is foreground, back-
ground `0' pels are preserved).
BBO_IGNORE specifies that eliminated pels are ignored (this is
useful for color).

Note that GpiBitBlt, as well as being unaffected by the GPI transforms and not
conforming to the MetaFile interchange architecture, is always output directly to
the device and never stored in a retained segment, regardless of drawing mode.
These restrictions do not apply to GpiwcBitBlt (described below).

GpiwcBitBIt

The world coordinate BitBlt function GpiwcBitBlt is very similar to GpiBitBlt but
has a number of important differences as follows:
1. Whereas like GpiBitBlt, the source rectangle coordinates are specified
as device coordinates, the GpiwcBitBlt target rectangle coordinates
are specified in world coordinates and are consequently subject to all
of the GPI transforms. As a consequence of this, the aptlpoints array
must always include all four source and target rectangle coordinates
and lcount must always be specified as four. The operation does not
(for IBM OS# Version 1.3 at least) support rotation and shear. Note
that a change to the Default Viewing 'Thansform would result in
GpiwcBitBlt output being coITectly positioned relative to other
graphics output, whereas GpiBiBlt output would be incoITectly posi-
tioned.
2. As a consequence of the above, target coordinates for GpiwcBitBlt are
inclusive at all boundaries whereas GpiBitBlt target coordinates are
inclusive at the bottom and left and exclusive at the top and right
boundaries. The effect of this in practice is that with page units of
PU_PELS and all transforms set to identity, the top right GpiBitBlt
target coordinates would need to be one greater than the correspond-
ing GpiwcBitBlt coordinates for an identical operation.
3. The GpiwcBitBlt source parameter is a bitmap handle rather than a
PS handle. The source, therefore, can only be a bitmap and this should
not be selected into a PS/OD_MEMORY DC. The source and target of
a GpiwcBitBlt operation are therefore limited to the following combi-
nations:
90 0S/2 PRESENTATION MANAGER GPI

a bitmap and device;


the sane bitmap; and
different bitmaps owned by the same device.
Bitmap ownership is transferred in the same way as for GpiBitBlt. If
a bitmap is owned by a different device, ownership is transfeITed by
selecting the bitmap into a Psroc for the new device (using
GpisetBitmap). The difference is that the bitmap should be deselected
before issuing GpiwcBitBlt.
4. For a GpiwcBitBlt operation from a color source to a monochrome
target, no source IMAGEBUNDLE attributes are available. Color
conversion is therefore performed using the IMAGEBUNDLE attri-
butes of the target PS and these are used to dete]rm.ine which source
bits are background (all other bits are assumed to be foreground).
5. Unlike GpiBitBlt, GpiwcBitBlt can be stored as a drawing order
inside a retained segment and conforms to the MetaFile interchange
architecture.

PATHS

Paths are picture functions that can be used for any of the following operations:
• Drawing a filled area (instead of using GpiBeginAreay/GpiEndArea).
• Drawing an unfilled outline that can include outline font characters.
• Defining an arbitrarily complex non-rectangular shape as a clip
boundary.
• Drawing geometric wide lines. These are lines, the appearance of
which is controlled by the line join, line end, and geometric line width
LINEBUNDLE attributes. Geometric line width can be defined by an
application and is subject to all the normal GPI transforms (scaling,
etc.). The resulting `geometric wide line' envelope definition is con-
tained in a modified path that can be filled in the same way as a
normal path to display the wide line.

Geometric Wide Line Attributes (used with Paths)


The LINEBUNDLE attributes and flags ®arenthesized) used with paths for
constructing geometric wide lines are as follows:

lGeomwidth (LBB_GEOM_WIDTH)
This specifies the geometric line width attribute in world coordinates.

usEnd (LBB_END)

This specifies the line end and attribute as one of:


LINEEND_FLAT,
DRAWING PRIMITIVES AND AFTRIBUTES 9`

LINEEND_SQUARE; and
LIREEND ROUND.

usJoin (LBB_JOIN)

This specifies the line join attribute as one of:


LINIOIN BEVEL;
LINEJOIN ROUND; and
LINEJOIN MITRE.

Path Dof[nltlon

A path is defined by issuing the drawing primitives and attributes for the required
(area, outline, clip path, or geometric wide line) path figures between:

GpiBeginpath; and
GpiEndpath.

GpiBeginpath and GpiEndpath, together with the path definition primitives can
be output directly in non-retained mode, accumulated in a retained segment, or
both, depending on the drawing mode. The path is created Out not displayed)
when the path definition primitives are actually output, whether directly, or from
a retained segment. Clearly, when stored in a retained segment, the same path can
be created at will merely by redrawing the segment. Note that the primitives (e.g.,
lines) inside a path bracket merely contribute to the path definition, and are not
actually displayed unless the completed path is subsequently drawn (e.g., using
Gpioutlinepath).
Path definition primitives (and orders stored inside a path in a retained seg-
ment) are specified in world coordinates and are therefore subject to all the normal
GPI transforms. However, once the path is created by outputting the path defini-
tion primitives, it becomes fixed in device coordinates and unaffected by subse-
quent transfo]rm. changes.
Any path can include outline font characters which, though normally filled, in
the contezit of a path bracket provide only the outline of the individual characters
as part of the path definition.
Only certain functions are valid inside a path. These are basically calls that
produce lines (including outline fonts) and certain attribute setting functions (see
the IBM OS# Hogramming Reference for a complete list of valid functions).
Note that for IBM OSA version 1.3 at least, there is an internal limit of 64K on
the maximum size of a path, and it is not possible to predict with any certainty
when this limit will be reached. When reached, an elTor is returned and the eITor
code PMERR_PATH_LIMIT_EXCEEDED will be logged.
92 OS/2 PRESENTATION MANAGER GPI

Paths are typically destroyed the first tilne they are used (see below).

Path Areas
To draw an area using paths, a path containing one or more figures describing the
required area shape must first be created. A path area fill operation is then
performed using the AREABUNDIE attributes by:

GpiFillpath

On completion of the fill, the path is destroyed.


The GpiFillpath options FPATH_AIJTERNATE and FPATH WINDING control
whether the fill is performed in alternate or in winding mode-and are equivalent
to the GpiBeginArea options described earlier. An example of area fill using path
functions is illustrated by the function DrawpathArea in Figure 3-15.

patharea.c */
L DrawpathArea(HPS hps)

Create a path defi.ni.ng a si.x poi.nted star made up of two tri.angles, and
fi.11 i.t usi.ng the FPATH_WINDING opti.on. Note that fi.1li.ng thi.s wi.th the
FPATH_ALTERNATE optl.on would leave the centre portl.on unfilled.

i.nputs: hps PS handle

B00L fRet /* B00L return


P0INTL ptlpoi.nt /* coordi.nate
P0INTL aptlpoi.nts[3] /* coordl.nate

/* begl'n path
fRet = Gpi.Begi.npath( hps /* -PS handle
1L /* -path 1.d (must be
in

Poi.nt.x = 100L: /* defi.ne path area shape */


PO1'nt.y -100L;

fRet = Gpi.Setcurrentposi.ti.on(hps, &ptlpoi.nt);

aptlpoi.nts[0].x = 200L:
aptlpoi.nts[0].y = 273L;
aptlpoi.nts[1].x = 300L:
aptlpoi.nts[1].y = 100L:
aptlpoi.nts[2].x = 100L;
aptlpoi.nts[2].y = 100L;

l'f (fRet)
fRet = Gpi.PolyLi.ne(hps, 3L, aptlpol.nts) != GPI_ERROR;

Figure 3.15 DrawpathArea Function.


DRAWING PRIMITIVES AND AFTRIBUTES 93

Pol'nt.x -100L;
Poi.nt.y = 215L;

fRet = Gpi.Setcurrentposi.tl.on(hps, &ptlpoi.nt):

aptlpoi.nts[0].x = 300L
aptlpoi.nts[0].y = 215L
aptlpoi.nts[1].x = 200L
aptlpoi.nts[1].y = 042L
aptlpoi.nts[2].x = 100L
aptlpoi.nts[2].y = 215L
l.f (fRet)
fRet Gpi.PolyLi.ne(hps, 3L, aptlpoi.nts) != GPI_ERROR:

l'f (fRet) /* end path */


fRet = Gpi.Endpath(hps); /* -PS handle */

l'f (fRet) /* set color */


fRet = Gpi.Setcolor(hps, CLR_RED):

if (fRet) /* fl.ll Path */


fRet = (B00L)Gpi.F1.1lpath( hps /* -PS handle */
1L /* -path i.d (must be 1) */
FPATH_WINDING /* -f,'11 Optl'On */
);

return ( fRet ) ;

Figure 3.15 (con££7?L4ed)

Path Outllnes
To draw an outline using paths, a path containing one or more figures defining the
required outline line shape must first be created. A path outline operation is
performed using the LINEBUNDLE attributes by:
Gpioutlinepath
On completion of drawing the outline, the path is destroyed.
This function can be used to draw an unfilled outline of an entire path including
that of any outline font characters in the path that would othe]owise be filled.

Geometr]c Wide Lines


To draw a geometric wide line using paths, a path containing one or more figures
describing the required shape must first be created. Any closed figures in the
definition should be explicitly closed using GpicloseFigure to ensure that line join
rather than line end attributes are used at the join between the staid and end
points. The path must next be `modified' using the geometric line width, line ].oin,
and line end LINEBUNDLE attributes. This is accomplished using
GpiModifypath. The result is a path describing the envelope of a geometric wide
line that can then be filled (and deleted) in the normal way using GpiFillpath.
Altermatively, the original path can be stroked (i.e., modified and filled) in a single
operation using Gpistrokepath.
94 OS/2 PRESENTATION MANAGER GPI

As mentioned above, the result of GpiModifypath is a path describing the


envelope of a geometr.ic wide line that can be filled the normal way. However, a
modified path is still a normal path and any valid path operation (including
GpiModifypath again) can be performed on it if required. Note that the fill
associatedwithGpistrokepathisalwaysperformedusingwindingmode,whereas
a path modified and filled separately using GpiModifypath and GpiFillpath can
use either alternate or winding mode for the fill operation. The main advantage of
Gpistrokepath is that it has a lower memory overhead than the two separate
operations and may therefore be successful under conditions where
GpiModifypath and GpiFillpath might fail due to insufficient memory.
Line join attributes are applied to line joins regardless of primitive type (e.g., to
join a line to an arc). The different line end and line ].oin attributes are illustrated
in Figure 3-16. An example of drawing geometric wide lines using path functions
is illustrated by the function DrawGeomwideLine in Figure 3-17.

Clip Paths
Tocreateaclippath,a(normal)pathcontainingoneormorefiguresdescribingthe
required clip shape must first be created. A path is converted to a clip path using:
Gpisetclippath

LINErmL"T

HNERE_SQUARE

I
HNEueL[Roun

LREOINJ- IINEJOIN_ROUND [JNEJOINJEVEL

Figure 3.16 Line-End and Lineuoin Geometric Wide Line Attributes.


DRAWING PRIMITIVES AND AFTRIBUTES 95

geomli.ne.c */
L DrawGeomwi.deLl.ne(HPS hps, B00L flopti.ons)

Create a path contai.ni.ng the requi.red li.nes and opti.onally close the
fi.gure. Modi.fy the path usl.ng the approprl.ate geometrl.c wl.de li.ne
attri.butes and fl.ll l.t to draw a geometri.c wi.de li.ne.

I.nputs: hps Ps handle


flopti.ons opti.ons (TRUE for close fi.gure)

B00L fRet /* B00L return code


P0INTL ptl poi.nt /* coordi.nate poi.nt
P0INTL aptlpoints[5] /* coordl.nate poi.nt array
LINEBUNDLE lbndLi.neBundle /* 11.ne bundle

path
fRet = Gpl.Begi.npath( hps andl e
1L path i.d must be 1
n
P o l' n -200L: /* defi.ne path (li.ne) shape
P o l. n -100L;

fRet = Gpl.Setcurrentposi.tl.on(hps, &ptlpoi.nt);

aptlpoi.nts[0].x = 100L:
aptlpoi.nts[0].y = 100L;
aptlpoi.nts[1].x = 100L:
aptlpoi.nts[1].y = 300L:
aptlpoi.nts[2].x = 300L:
aptlpol.nts[2].y = 300L:
aptlpoi.nts[3].x = 300L:
aptlpol.nts[3].y = 100L:
aptlpoi.nts[4].x = 200L;
aptlpoi.nts[4].y = 100L:
l'f (fRet)
fRet = Gpl.PolyLi.ne(hps 5L, aptlpoi.nts) != GPI_ERROR;

1.f (fRet && fl0ptl.ons) /* optl.onal close fi.gure */


fRet = Gpi.CloseFi.gure(hps): /* -PS handle */

l'f (fRet) /* end path */


fRet = Gpi.Endpath(hps); /* -PS handle */

1 b n d L 1. n e a u n d 1 e . 1 G e o in W 1. d t h 20L
l bnd Li neBundl e . us End LINEEND ROUND
1 b n d L i. n e a u n d 1 e . u s J o i. n LINEJ0IFT BEVEL

l'f (fRet)
fRet = Gpi.SetAttrs( hps /* set geometrl.c ll.ne attri.butes
PRIM_LINE /* -attri.bute type
L B B_G EON_W I DTH /* -attrl.butes mask
LBB_END
L B B_J 0 I N
0L /* -defaults mask
& 1 b n d L 1. n e 8 u n d 1 e /* -attrl.bute bundle
in

Figure 3.17 DrawGeomwideLine Function.


96 OS/2 PRESENTATION MANAGER GPI

1'f (fRet) /* set cll.p path */


fRet = Gpl.Modi.fypath( hps /* -PS handle */
1L /* -path control */
MPATH_STROKE /* -Optl'ons */
);

l'f (fRet) /* set color */


fRet = Gpi.Setcolor(hps, CLR_RED);

l'f (fRet) /* fl.ll path */


fRet = (B00L)Gpi.Fi.llpath( hps /* -PS handle */
.1L /* -path I.d (must be 1) */
FPATH_WINDING /* -fi.11 opti.on */
n
retu rn ( f Ret ) ;
)

Figure 3.17 (conffnz/ecz)

Gpisetclippath has options, SCP_AIJTERNATE and SCP_WINDING, controlling


whether the clip path is constructed using altermate or winding mode. These are
similar to the GpiBeginArea options described earlier. Other options, SCP RESET
and SCP_AND, together with the path control flag parameter (OL or lLJ specify
whether the existing clip path is to be reset to infinity or modified to the intersec-
tion of the existing clip path and the new path definition.
Once converted to a clip path, the original path is deleted. The clip path is not a
normal path and is not available for use with normal path functions such as
GpiFillpath. An example of clip path definition is illustrated by the function
Createclippath in Figure 3-18.

cli.ppath.c */
OL Createcli.ppath(HPS hps)

Create a path defi.ni.ng a si.x poi.nted star made up of two tri.angles and
select 1.t as the cll.p path.

I.nputs: hps PS handle

B00L fRet /* B00L return


P0INTL ptlpoi.nt /* coordi.nate
P0INTL aptlpoi.nts[3] /* coordi.nate

/* begl'n path
fRet = Gpl.Begl.npath( hps /* PS handle
1L /* path i.d must be 1
in

ptlpoi.nt.x = 100L: /* defl.ne path cll.p shape */


ptlpo1'nt.y -100L;
if (fRet)
fRet = Gpl.Setcurrentposi.ti.on(hps, &ptlpol.nt);

Figure 3.18 Createclippath Function.


DRAWING PRIMITIVES AND AFTRIBUTES 97

aptlpoi.nts[0].x = 200L;
aptlpoi.nts[0].y = 273L:
aptlpol.nts[1].x = 300L;
aptlpol.nts[1].y = 100L;
aptlpoi.nts[2].x = 100L;
aptlpoi.nts[2].y = 100L;

l'f (fRet)
fRet = Gpl.PolyLl.ne(hps, 3L, aptlpol.nts) != GPI_ERROR:

Pol.nt.x = 100L;
Poi.nt.y = 215L;

fRet = Gpl.Setcurrentposi.tl.on(hps, &ptlpoi.nt):

aptlpoi.nts[0].x = 300L;
aptlpol.nts[0].y = 215L;
aptlpoi.nts[1].x = 200L:
aptlpoi.nts[1].y = 042L;
aptlpoi.nts[2].x = 100L:
aptlpol.nts[2].y = 215L;
1'f (fRet)
fRet Gpi.PolyLi.ne(hps, 3L, aptlpol.nts) != GPI_ERROR;

1'f (fRet)
fRet = Gpi.Endpath(hps); /* end path */

l'f (fRet) /* set cli.p path */


fRet = Gpi.Setcli.ppath( hps /* -PS handle */
.1L /* -path control */
SCP WINDING /* -Opt,.ons */
SOP_AND

return ( fRet ) ;

Figure 3.18 (co7?££7"eczJ


Fonts

Fonts are resources that allow text to be displayed in a variety of sizes, typefaces
(e.g.,Roman,Courier),andstyles(italic,bold,etc.).Rasterfontcharactershavefixed
size, whereas outline font characters can be scaled to any size using the character
box attribute and GPI transforms. Individual outline font characters or text strings
can be scaled independently or as part of an entire graphics picture or text page.
The GPI enables an application to specify the font to be used for drawing:
• Text.
• Characters within a graphics picture.
• Markers.
• Area fill patterns.
In the case of markers and patterns, font characters may be used in place of
markers and patterns from the standard marker and pattern sets. A font character
designed for text, however, may not be ideally suited for use as a marker that
requires precise positioning of its center, as the font design may not position a
character symbol centrally within its definition space.
Fonts may be shared by all applications across the entire system, relieving
applications and MetaFiles of the need to carry the individual character glyph
definitions. They need be concerned only with the attributes (facename, point size,
etc.) of the required fonts.
Font sizes are traditionally specified as the visible character height on the
output device in points, where a point is a `printers' point measuring 1/72 inches
(a 10 point font, for example, would therefore have a height of 10/72 or 0.139
inches). Font point size is roughly equivalent to the maximum baseline extent (i.e.,
the sum of the maximum ascender and maximum descender) in device coordi-
nates, but this is only an approximation. Font point size is not, in fact, precisely
defined in terms of any measurable characteristic of a visible character.

98
FO NTS 99

Characters output from an application may be displayed using fonts from any
of the following sources:
1. The default courier system outline font.
2. A font from a user supplied font file. This can include a raster font
created using the Font Editor and, for IBM OSA Version 1.3, Adobe
Type 1 Outline fonts (these are supplied with OS# and can be also
purchased independently). An Adobe Type 1 font is supplied as an
.AFM (Adobe Font Metrics) and a .PFB (Postscript Font Binary) file,
which are in the same format as soft fonts downloaded by the pscript
driver. These are similar to the .PSF files described below. User
supplied fonts of either type may be installed using the Control Panel
or loaded using Gpil.oadFonts.
3. A device font (i.e., a font suitable for use with only one particular
device).
Device fonts can include fonts built into the device hardware or driver,
provided on a separate device font card or cartridge, or provided as
downloadable `soft fonts' on diskette. See chapter 12 for a discussion of
printer fonts.
Normally a raster or outline device font will be provided as the default
font for a device. Devices that do not provide any device fonts will
normally use a built-in system Courier rasher font as their default.
4. A generic font from a system font file. These are pre-installed via the
Control Panel or can be loaded using GpiLoadFonts.
On IBM OS/2 Version 1.3, the following pre-installed system font files
are provided for use with Presentation Manager:
courier.fon;
times.fon;
helv.fon;
sysmono.fon;
courier.psf;
helvetic.psf; and
timesr-.psf.
Courier.fon, times.fon, helv.fon, and sysmono.fon provide a range of
raster fonts with various point sizes and device resolutions and the
following Facenames (or typefaces):
Courier;
Helv;
Tins ELn; and
System Monospaced.
100 0S/2 PRESENTATION MANAGER GPI

The 'Ihs Rmn and Helv fonts are proportionally spaced whereas
Courier and System Monospaced are monospaced (i.e., fixed pitch).
The .PSF files are a compiled version of the .AFM and .PFB files
described above. The courier.psf, helvetic.psf and timesnrm..psf files
are provided with IBM OSA Version 1.3 and provide a range of Adobe
Type 1 Outline fonts with the following Facenalnes:
Courier;
Courier Italic;
Courier Bold;
Courier Bold Italic;
HelveticaTM;

Helvetica Italic;
Helvetica Bold;
Helvetica Bold Italic;
Times New RomanTM;
Times New Roman Italic;
Times New Roman Bold; and
Times New Roman Bold Italic.
These same fonts also support the following previously supported
outline font Facenames for compatibility with 1.1 and 1.2 applications.
Helv;
Helv Italic;
Helv Bold;
Helv Bold Italic;
Tins ELn;
Tins ELn Italic;
Tins ELn Bold; and
Tins Rmn Bold Italic.

PUBLIC AND PRIVATE FONTS

Fonts may be either public or private. A public font is one that is available to all
application processes within the system whereas a private font is available only to
the single application process from which it was loaded. External font files,
FONTS 101

including both system and user supplied font files, can be installed as public fonts
(and deleted) using the Control Panel or loaded as private fonts from an applica-
tion using GpiljoadFonts. All device fonts are public fonts.
It is recommended that applications should normally use public rather than
private fonts. This is because private fonts are not available on a different process
(e.g., the print process) from that on which they were loaded. They will not,
therefore, be available to print jobs with data type PM_Q_STD that are printed
via the spooler ®rint jobs with data type PM_Q_RAW will print private fonts
successfully but PM_Q_S'ID is the recommended method of printing).

MOHOSPACED AND PROPORTIONAL FONTS

Monospaced fonts are fonts for which every character has the same width, whereas
proportional fonts provide characters with different widths according to the indi-
vidual character shapes. FToportional fonts are generally considered to produce
text with a much more pleasing appearance than that obtained using monospaced
fonts but monospaced fonts are useful in situations where vertical alignment of
characters is important (e.g., for computer programs).

RASTER AND OUTLIIIE FONTS

Raster fonts are fonts for which each character is defined as a fixed size bitmap or
rectangular pixel image. Outline fonts are fonts for which each character is defined
by a sequence of vector strokes and curves defining a closed figure that is
optionally filled. Raster (or image) font characters are fixed size whereas outline
(or vector) font characters are scalable and are transformed by the character box
attribute and the current transforms.
On IBM OSA Version 1.2, the outline fonts provided (originally within cou-
rier.fon, helv.fon, and times.fon) were only really suitable for displaying large
characters. When scaled to a small size, rounding errors caused the stroke
thickness to vary and their appearance became rather ugly. This was remedied by
the Adobe Type ManagerTM provided with IBM OSA 1.3 that supports Adobe Type
1 Fonts enabling outline fonts to be used to display high quality text over a wide
range of sizes, from quite small to very large.
The Adobe Type 1 Fonts also provide kerning support. This is an additional
refinement of proportional spacing which, for certain character pairs (e.g., Ta, To,
Th, We, and Yo), allows one character to overhang another providing a further
improvement in the text appearance (see Figure 4-1). The function Kermcharstr-
ing in Figure 4-2 is equivalent to Gpicharstring with keming adjustment applied
to each pair of characters for which keming inform.ation is available. This function
issues GpiQuerywidthTable to query the width table for all the characters in the
codepage. It then queries the font metrics to determine the number of keming
pairs available before querying issuing GpiQueryKerningpairs to obtain the kem-
ing pair information. An aITay of widths for the characters to be displayed is then
102 OS/2 PRESENTATION MANAGER GPI

ITo AVA I L

RTo AVAIL
Figure 4.1 Kemed and Unkemed Text.

kernchar.c */
OL Kerncharstri.ng(HPS hps, LONG ICount, PCH pchstrl.ng)

Di.splay the character stri.ng with the approprl.ate kerning adjustments.

i.nputs: hps Ps handle


lcount count of characters
pchstrl.ng character stri.ng

B00L fRet = FALSE /* B00L return code


FONTMETRICS fmMetri.cs /* font metrl.cs
PLONG alwi.dths = NULL /* character width array
PKERNINGPAIRS akrnprs = NULL /* kerni.ng pal.r array
PLONG alw1.dthTable = NULL /* wi.dth table
LONG 1 /* loop vari.able
LONG J /* loop varl.able

/* allocate memory for */


alwi.dths = malloc((SHORT)lcount*si.zeof(LONG)): /* character stri.ng wi.dth */
/* ar.r.ay */

I.f (alwi.dths!=NULL) /* allocate memory for


alw1.dthTable = malloc(256*sizeof(LONG)): /* width table

I.f (alwi.dthTable!=NULL) query wi.dth table


fRet = Gpi.Ouerywi.dthTable( hps -PS handle
OL
-fl.rst character
256L -count
alwl.dthTable returned wi.dth
):

l.f (fRet) /* query font metrl.cs


fRet = Gpi.QueryFontMetri.cs( hps /* -Ps handle
(LONG)si.zeof(FONTMETRICS)/* -metri.cs length
&fmMetrl.cs /* -returned metrl.cs
in

Figure 4.2 Kemcharstring Function.


FONTS

l.f (fRet && fmMetri.cs.sKerni.ngpai.rs!=0) /* 1.f kerni.ng pal.rs exl.st


( /* allocate memory for
/* kerni.ng pal.rs

akrnprs = malloc(fmMetri.cs.sKerni.ngpai.rs*si.zeof (KERNINGPAIRS)):


fRet = (akrnprs!=NULL);
*/
i:e{f±e:;I.oueryKerni.ngpairs( hps ;: 9;:r%a#:]r:l.ng pal.rs */
fmMetri.cs.sKerni.ngpal.rs /* -count */
akrnprs /* -returned Kern pal.rs */
) != GPI_ALTERROR;
)

l'f (fRet)
(
for (1.=0 :1.<1count; I.++ ) /* assemble character */
alwi.dths[i.] = alwi.dthTable[pchstri.ng[i]]: /* strl.ng wl.dth array */

for (I.=0: i.<lcount-1: 1.++ ) /* for each character */


( /* pal.r 1.n the stri.ng */

for (j=0 ;j<fmMetri.cs.sKernl.ngpai.rs; j++ ) /* search formatchi.ng */


( /* kerni.ng pal.r */

1.f ( pchstri.ng[i.] == (UCHAR)akrnprs[j].sFi.rstchar &&/* 1.f matchi.ng */


pchstri.ng[1.+1] == (UCHAR)akrnprs[j].ssecondchar/* kerni.ng pal.r */
/* found */

alwi.dths[l.] += akrnprs[j].sKerni.ngAmount; /* adjust wi.dth*/


break; /* and break */

/* draw the character


/* usl.ng character strl.ng
/* wi.dth array
fRet = (B00L)Gpi.Charstri.ngpos( hps /* -PS handle
NULL /* -rectangle
CHS_VECTOR /* -Optl'Ons
lcount /* -count
' pchstrl'ng /* -character stri.ng
alwidths /* -wl.dth array
in
)

f r e e ( a 1 W i. d t h s ) ;
f ree( akrnprs ) ;
f r e e ( a 1 W i. d t h T a b 1 e ) ;

return ( fRet ) :

Figure 4.2 (co7i££7}zJecz)

assembled from the width table inform.ation and each pair of characters is com-
pared for a match against each kerning pair. If a match is found then the keming
value is used to adjust the corresponding character width (for the first character
of the pair). The character string is displayed using Gpicharstringpos with the
character width array used as a vector of increment values. Clearly, if this function
were to be used multiple times for the same font then performance would be
lob 0S/2 PRESENTATION MANAGER GPI

improved by providing the width table and kerning pair arrays as parameters
rather than querying these for every character string. Also, the kerhing pairs are
returned in order of codepoint and a binary search could therefore be used to
improve performance.
Support for Adobe Type 1 Fonts requires no change to an application which
supports the earlier OSA outline fonts.

FONT METRI0S

Font terminology is derived from old fashioned printing technology giving rise to
terms such as `leading' ®ronounced ledding) from the use of metallic lead in early
printing.
Fonts are described by a collection of metrics contained in the fields of a
FONTMETRICS stmcture as follows:
szFamilyname;
szFacename;
idRegistry;
uscodepage;
lEmHeight;
lxHeight;
lMaxAscender;
lMaxDescender;
lIlowercaseAscent;
lljowercaseDescent;
llntermalLeading;
lExtemalLeading;
lAvecharwidth;
lMancharlnc;
lEmlnc;
lMarBaselineExt;
scharslope;
slnlineDir;
scharRot;
usweightclass;
FONTS 105

uswidthclass;
sXDeviceRes;
sYDeviceRes;
sFirstchar;
sLastchar;
sDefaultchar;
sBreakchar;
sNominalpointsize;
sMinimumpointsize;
sMaximumpointsize;
fsType;
fsDefn;
fsselection;
fscapabilities;
lsubscriptxsize;
lsubscriptYsize;
lsubscriptxoffset;
lsubscriptYoffset;
lsuperscriptxsize;
lsuperscriptYsize;
lsuperscriptxoffset;
lsuperscriptYoffset;
lunderscoresize;
lunderscoreposition;
lstrikeoutsize;
lstrikeoutposition;
sKemingpairs;
sFamilyclass; and
lMatch.
The font metrics can be queried for all available fonts using GpiQueryFonts and,
for the currently selected font, using GpiQueryFontMetrics. The FONTMETRICS
106 OS/2 PRESENTATION MANAGER GPI

structure includes szFamilyname (Family name) szFacename (typefal


sNominalpointsize, ®oint size) uscodepage (code page), fsDefii flags specifying
whether or not the font type is outline QrM_DEFN_OUTLINE) or raster, and a
ntmber of important dimensions, some of which are illustrated in Figure 4-3.
T
Font selection is normally performed using szFacename, the outline/raster flag
Q7M_DEFN_OUTLINE), and, for raster fonts only, sNominalpointsize,
sXDeviceRes, and sYDeviceRes (the latter defining the horizontal and vertical
device resolution for which the font was designed). szFamilyname is a more
general name than szFacename and can be used for font matching when a font
with the exact szFacename required is not available. A font, for example, with
szFacename of "Courier Bold Italic" will have an szFamilyname of "Courier".
The metrics lMaxcharlnc and lAvecharwidth are useful for horizontal charac-
ter positioning and determining the average and maximum widths of a text field.
The vertical spacing required for rows of text can be determined by
lMakBaselineExt+lExtemalLeading but this is not always ideal, as it may produce
different results with different fonts of the same point size. IEmHeight* 1.2 is an
alternative method that is sometimes preferred. IExtemalLeading (which is often

I •Baseline

lMaxDe scender

J
lM axc harlnc lAv e charwi dth lExtemalLeading

llntemalLeading
-lincExt

lMaxBaseeicht
lEmH
(&C hay Box Height)I
Baseline

Lri:Ego:irse Em Squre
(& Outline Font Character Box Atthbute)

Figure 4.3 Important Font Dimensions (monospaced font).


FO NTs lou

zero) is the maximum recommended inter-row spacing that can be added to


lMaxBaselineExt without affecting the pleasing appearance of the text, and can
be reduced as required. The top row of text should be positioned at least
lMaxAscender+lExtemalLeading below the top of the output area. Note that
lMaxBaselineExt is equal to the sum of lMaxAscender and lMaxDescender.
'twootherimportantmetricsarelEmHeightandlEmlncthattogetherdefinethe
EmSquare.TheEmSquareisoftenviewedasrepresentingthesizeoftheletter`M'
but this is incorrect. The lEmHeight metric, in fact, represents the font point size
converted(fromdevicespace)intoworldcoordinatesandthesunoflEmHeightplus
llntermalLeadingisalsoequaltolMaxBaselineExt.Asstatedearlier,fontpointsize
is not precisely defined in terms of any measurable characteristic of the visible
characters and neither, therefore, are lEmHeight and lEmlnc.
For outline fonts, lEmHeight and lEmlnc are set to the character box attribute
dimensions and can therefore be controlled directly using GpisetcharBox and
GpisetAttrs. Other width and height metrics such as lAvecharwidth and
lMaxBaselineExt are scaled in the same proportion. Clearly, character width will
vary as the character box attribute changes, however, the ratio Characterwidth
AEmlnc is normally constant for a given character of a particular font or, for a
non-proportional font, for all characters in the font (i.e., lAvecharwidth/lEmlnc).
The horizontal character spacing of outline characters (and raster characters
drawn using character mode CM_MODE2) can therefore be determined by
CharacterBox.cx*CharacterwidtMEmlnc.
The font metrics, when queried, are returned by the system in world coordi-
nates. Therefore for raster font characters, these will vary each time there is any
change to one of the GPI transfo]rm matrices. If lMaxBaselineExt and lAvechar
Width are being used for raster font creation and there has been any transform
change since the font metrics were last queried, then they must be queried again
before being used as parameters to GpicreateLogFont. Incorrect values will cause
the font match to fail, the function will return For\IT` DEFAULT instead of
FONT_MATCH,andadefaultfont(whichmaybeanoutlin-efont)willbeprovided
in place of that requested.
Not all the FON'IMETRICS fields are useful to an application. The sFirstchar
and sLastchar fields, for example, define the total glyphs in a font rather than the
subset available to a particular codepage.

FONT SELECTION AND LOGICAL FONT CREATION

Font selection is performed by issuing GpiQueryFonts to query the metrics of the


available fonts,searchingthereturmedmetricsforasuitablefontandthenissuing
GpicreateLogFont to create a logical font describing the required font.
GpicreateLogFont specifies an application defined identifier or set id (sometimes
called an lcid), which is specified subsequently with Gpisetcharset,
GpisetMarkerset, Gpisetpattemset, or GpisetAttrs to select the font for draw-
ing. A logical font is deleted using GpiDeletesetld.
Fonts are normally selected by Facename (szFacename) and, in the case of
108 OS/2 PRESENTATION MANAGER GPI

raster fonts only, point size (outline font point size is controlled by the transforms
and character box attribute).
GpiQueryFonts can specify the required szFacename value (or NULL if all
available fonts are to be returned) and whether public (QF_PUBLIC) fonts, private
(QF_PRIVATE) fonts, or both, are to be returned.
Included in the FON'ITVIETRICS information is a local font match number
(lMatch) that, subject to certain limitations, can be used to simplify font selection
by providing a `quick and dirty' alternative method. The lMatch value and
szFacename uniquely identify a font within the system and can be specified
together on GpicreatellogFont in place of the other metrics. The lMatch value
should not, however, be used for font selection in the following situations:
1. When the target PS is associated with a MetaFile DC ®ecause the
lMatch value will not be recorded in the MetaFile).
2. When printing remotely on a network print server (lMatch value is
unique only within the local system).
3. In any situation where the lMatch value would need to remain valid
after re-IPL (e.g., in a held print file).
IMatch value is suitable for direct printing, local printing via the spooler that
completes before re-IPL, or any queued printing using data type PM_Q_RAW.
For raster fonts, the alternative method to specifying the lMatch value on
GpicreateLogFont is to specify lMaxBaselineExt and lAvecharwidth in addition
to the required font szFacename. These must exactly match the values for the
required font or the match will fail and a default font will be returned. If any
transforms have changed since the font metrics were last queried, then the metrics
must be queried again to obtain updated values as described above. Similarly,
when printing via the spooler (i.e., with an OD_QUEUED DC) using data type
PM_Q_STD, to minilnize the risk of the font match failing on the print process, the
DevopenDC (DEVOPENDATA) pszQueueHrocparams should specify real size
(i.e., "XFM=0") rather than default which is `scale to fit.'
For outline fonts, the match number buys little. It is sufficient to specify only
szFacename together with the FATI`R FONTUSE OUTLINE and/or
FAITR FONTUSE TRANSFORMABLE fsFont-Use flags o= GpicreateLegFont.
As an o-utline font :an be scaled at will, lMaxBaseLineExt and lAvecharwidth
have little meaning and are ignored by the font matching algorithm.
GpicreateLogFont can also specify any combination of the following fsselection
indicators:
FATI`R SEL ITALIC;
FATrR SEL uNDERscoRE;
FATrR SEL STRIKEOUT, or
FAITR SEL BOLD.
These will cause the system to apply italic, underscore, strikeout, and bold
sinulations to non-device raster characters (and also outline font characters
FO NTS 109

although they are not really intended for, or ideal with the latter). These simula-
tions are in addition to any (italic, etc.) characteristics included in the font design.
These flags may not always be honored for device fonts.
For outline font characters, the FATI'RS_SEL_OU'ILINE flag causes unfilled
outline characters to be drawn (this was originally provided as a way of improving
performance).
When creating a raster font of specified point size, it is necessary to search the
metrics of the available fonts for a raster font with the required point size that also
matches the resolution of the target device. This is illustrated by the functions
CreateRasterFont and CreateRasterFont_lMatch in Figures 4-4 and 4-5. Note
that the CAPS_HORIZONTAL_FONT_RES and CAPS VERTICAL FONT RES
values returned from DevQuerycaps are conveniently -specified in ;els per-inch
(unlike CAPS_HORIZONTAL_RESOLUTION and CAPS_VERTICAL RESOLU-
TION which are in pels per meter). A careful analysis of these values-will reveal
that for most displays, the resolution for font selection is higher than the true
device resolution causing matching raster font characters to appear larger than
expected. This is quite intentional and is based on the observation that the normal
viewing distance for a display screen is significantly larger than that of printed
output. It is therefore considered desirable for characters to appear larger on a
display screen than when printed.
This size difference is not necessarily ideal. It makes WYSIWYG between screen
and printer difficult with raster fonts. Also, if, for example, GpiQuerycharstringpos
is used for raster font character positioning when creating a MetaFile for
subsequent printing, the position values obtained and recorded in the MetaFile
will be incorrect for the printer, even for a printer font with a matching Facename
and point size. This is because a MetaFile assumes compatibility with the display
and the MetaFile and printer font sizes will be different. To overcome this, a
separate PS associated with a printer DC and a separate printer font must be used
for determining the character positions recorded in the MetaFile.
The function CreateoutlineFont in Figure 4-6 illustrates outline font creation
and the function AllocatesetlD in Figure 4-7 illustrates the use of
GpiQueryNumbersetlds and GpiQuerysetlds to determine the set ids already in
use and to allocate an unused value.
When selecting a font, it is often desirable for performance reasons (and appear-
ance) to select a device rather than a generic font. This can be established by
examining either the fsDefii flags or the lMatch value in the FON'IMETRICS. For
a device font, the FM_DEFN_GENERIC flag is not set and the lMatch value is
negative (I have found that, for some drivers, the lMatch approach seems slightly
more reliable).

OUTLINE FONT SCALING USING CHARACTER BOX ATTRIBUTE

Outline fonts are designed in a notional font definition space above world coordi-
nate space (see Figure 7-1). The dimensions of this space, which is normally a
1000xl0cO square, are returned as the sXDeviceRes and sYDeviceRes
110 OS/2 PRESENTATION MANAGER GPI

FONTRETRICS fields and these particular metrics are unaffected by the trans-
forms and character box attribute. The transfo]rm from font definition space to
world coordinate space is defined by the ratio of the sXDeviceRes and
sYDeviceRes rectangle in font definition space and the character box attribute
rectangle in world coordinate space. For an outline font, the character box
attribute is, in fact, the same as the Em Square. As mentioned earlier, it is the
Em Square dimensions lEmHeight and lEmlnc that are set by the character box
attribute height and width values (for an outline font). It is therefore possible for
lAvecharwidth and lMaxBaseLineExt to exceed the character box dimensions
and for these to differ between fonts of different design, even though the character
box attribute dimensions may be identical. The effect of the character box attri-
bute on horizontal spacing of outline and CM_MODE2 raster font characters was
described earlier.
The function SetoutlineFontpointsize in Figure 4-8 illustrates how to scale an
outline font to a specified point size. Note that the lEmHeight metric is a measure
of font point size in world coordinates and, for an outline font, is equal to the height
of the character box attribute. The required point size is achieved by determining
the size in pels of the required font point size, converting this to world coordinates
to provide the required lEmHeight value and specifying this value as the character
box attribute dimensions.
The function ScaleoutlineTOFixed in Figure 4-9 illustrates how to scale an
outline font size to match that of a specified raster font. Note that this is achieved
by using the character box attribute to set the outline font lEmHeight value to
match that of the raster font. Any remaining size differences between outline and
raster font characters (even with the same szFacename) are due to differences in
font design. Alternative scaling algorithms can use different metrics such as
lxHeight (and can give better results). This is illustrated by the function
ScaleoutlineTOFixed2 in Figure 4-10. This queries the metrics of the raster font
and then sets the character box attribute to a known value of 1000xl000 before
querying the metrics of the outline font. The character box attribute is then scaled
by the amount (i.e., Raster_lxHeighi/Outline_lxHeight) required to set the outline
lxHeight to a value that matches the raster font.
A similar approach is used to set the horizontal pitch of a font to a specified value
in characters per inch, as illustrated by the function SetHorizontalpitch in Figure
4-11. Here the character box attribute is again set to a known value of 1000xl000
before querying the metrics of the outline font. The character box attribute is then
scaled by the value (i.e., Required_lAvecharwidth/Old_lAvecharwidth) required
to set the pitch to the specified value (where Required_lAvecharwidth in pels is
determined from lxResolution/pitch). Note that average character width must be
converted from world to device coordinates using Gpiconvert.
As mentioned above, outline fonts are normally defined in a 1000xl000 square
definition space. The major exceptions to this are built in device outline fonts such
as those provided by a plotter. To obtain ideally (i.e., as designed) outline font
characters, the aspect ratio of the character box attribute should match that of the
sXDeviceRes and sYDeviceRes font metric dimensions (for an isotropic coordinate
system).
FONTS 111

GPI AND FONT CODEPAGES

The system default codepage is the first codepage specified in the CODEPAGE
command of CONFIG.SYS, or is codepage 850 if CONFIG.SYS contains no
CODEPAGE command. Ovote that Dossetcp cannot be used in a Hesentation
Manager application but both Dossetnroccp and the CHCP command can be used
to switch between the two codepages specified in CONFIG.SYS). The GPI Hesen-
tation Space codepage is used for displaying GPI font characters and this will
default to the process codepage that will be either the system default or some other
value set by DossetHocCp or CHCP.
Regardless of the values specified in the CONFIG.SYS CODEPAGE command,
a GPI PS codepage can be set to any of the following values using Gpisetcp:
ASCII US ENGLISH 437
ASCII MUIJTILINGUAL 850
ASCII PORTUGUESE 860
ASCII CANADIAN FRENCH 863
ASCII NORWEGIAN 865
ASCII DESKTOP PUBLISHING lco4
EBCDIC US ENGLISH 37
EBCDIC AUSTRIAN GERMAN 273
EBCDIC BELGIAN 500
EBCDIC DANISH NORWEGIAN 277
EBCDIC FINNISH SWEDISH 278
EBCDIC ITALIAN 280
EBCDIC PORTUGUESE 37
EBCDIC SPANISH 284
EBCDIC UK ENGLISH 285
EBCDIC FRENCH 297
EBCDIC INTERNATIONAL 500
EBCDIC BELGIAN (M) 274 supported for migration
purposes
EBCDlc PORTUGUESE (ro 282 supported for migration
purposes
The GPI PS codepage can be queried using GpiQuerycp.
System font files are designed to provide a universal character set that includes
allcharactersrequiredbyalloftheabovecodepages,andtoprovidethenecessary
I+2 0S/2 PRESENTATION MANAGER GPI

codepoint to character mappings required by each codepage. For a font that


supports all of the above codepages, GpiQueryFonts will return a value of zero in
the FON"ETRICS uscodepage field, whereas for a font that supports only a
single codepage this non-zero codepage value will be returned.
When creating a logical font using Gpicreatel.ogFont, the codepage can be
defaulted by specifying zero in the uscodepage field of the FATI`RS structure. It
is normally safer, however, to specify the codepage explicitly (e.g., by using the
current GPI codepage value as shown in the CreateRasterFont example).

BITMAP SET IDS

In addition to its use for specifying a logical font as a character, pattern, or marker
set as described above, a set id can also be used to define a bitmap as an area fill
pattern. To use a bitmap for area fill, the bitmap must be tagged with a set id using
GpisetBitmapld. The bitmap can then be selected as the current area fill pattern
using Gpisetpattemset or GpisetAttrs in the normal way. Note that
Gpisetpattern is not required as this attribute is ignored for bitmaps. A bitmap
set id is deleted using GpiDeletesetld.
Note that a bitmap may be simplified when used as an area fill patterm, for
example, it will be converted to monochrome and only part of a large bitmap (e.g.,
an 8x8 pel rectangle) might be used.

crasfont.c */
G CreateRasterFont (HPS hps)

Create a logi.Gal font for a 12 pol.nt publi.c Courl.er raster font wl.thout
usl.ng lMatch and return the set i.d (or GPI_ERROR for error).

i.nputs: hps Ps handle

returns: LONG Set ID (Lci.d) of the newly created font (or GPI_ERROR)

#defi.ne P0INTSIZE 120


#defl.ne FACENAME .`Courier"
#defl.ne FONTNAME "FONT01"

PFONTMETRICS afmMetri.cs = NULL /* poi.nter to FONTMETRICS array


LONG 1 NumFonts /* number of fonts aval.lable
LONG lRemFonts = GPI_ALTERROR /* number fonts not returned
LONG I Req Fonts /* number fonts requested
LONG 1 XDevRes /* actual X devl.ce resolutl.on
LONG 1 YDevRes /* actual Y devi.ce resolutl.on
B00L f Ret = FALSE /* B00L return code
HDC hdc = NULL /* DC handle
LONG ILci.d = GPI_ERROR /* set ltd
INT 1 /* array 1.ndex
USHORT uscodepage = GPI_ERROR /* codepage
FATTRS fatAttrs /* font attrl.butes

Figure 4.4 CreateRasterFont Function.


FONTS 113

/ :.*************************************************************************** 1

j§ :!;::in;::i:::::::i:::;::i::i:i;:;r:::eq|::yin:;: #:::Tr¥st:o:1:?Sa::bi:: ;j
/ ****************************************************************************-/

lReqFonts = OL;
Query Number of
lNumFonts = Gpl.QueryFonts( hps -PS handle
QF_PUBLIC Opti ons
FACENAME facename
&lReqFonts number of fonts
OL metrl.cs length
NULL returned metri.cs
in
I.f ((1NumFonts!=GPI_ALTERROR)&&(lNumFonts!= OL)) /* allocate memory for
afmMetri.cs = malloc((SHORT)(lNumFonts*si.zeof(FONTMETRICS))): /* metri.cs

I.fi#::::T.=SG;=Q:::;}onts( hps (: 9;:r%a::|: Metrics

QF_PUBLIC /* -opti.ons
FACENAME /* -facename
&1NumFonts /* -number of fonts
(LONG)si.zeof(FONTMETRICS) /* -metri.cs length
. afmMetrl.cs /* -returned metri.cs
n
/ :.*************************************************************************** I
/* */
/* Query the actual horl.zontal and vertl.cal resolutl.on for the devi.ce. */
/* */
/ ****************************************************************************' I

1.f (lRemFonts != GPI_ALTERROR)


hdc = Gpl.QueryDevl.ce(hps); /* query associ.ated DC handle */

1.f ((hdc!=NULL)&&(hdc!=HDC_ERROR)) /* query actual devi.ce X res


fRet = DevQuerycaps( hdc /* -DC handle
CAPS_HORIZONTAL_FONT_RES /* -fi.rst I.tern requested
1L /* -number of caps requested
&lxDevRes /* -returned caps
in

l'f (fRet) /* query actual devi.ce Y res


fRet = DevQuerycaps( hdc /* -DC handle
CAPS_VERTICAL_FONT_RES /* -fi.rst l.tern requested
1L /* -number of caps requested
&1YDevRes /* -returned caps
in

Figure 4.4 (con££7izAed)


114 OS/2 PRESENTATION MANAGER GPI

/ **************************************************************************** /
/**/
/* Search the font metri.cs for a font that sati.sfi.es all of the followi.ng */
/* condi.ti.ons and create a logi.cal font for i.t wl.thout usi.ng lMatch: */
/* font l.s raster */
/* facename matches requi.red facename */
/* font devi.ce resoluti.on matches actual devi.ce resoluti.on hori.zontally */
/* font devl.ce resoluti.on matches actual devl.ce resolutl.on verti.cally */
/**/
/ **************************************************************************** /

l'f (fRet)
{ /* step through and exami.ne */
for (I. = 0; i < (INT)lNumFonts: 1.++) /* metri.cs for each font */
(
(!(afmMetrl.cs[l.].fsDefn & FM_DEFN_OUTLINE) /* check for raster
(strcmp(afmMetri.cs[i.].szFacename, FACENAME)) /* compare facename
afmMetri.cs[i.].sNomi.nalpoi.ntsi.ze == P0INTSIZE)/* compare poi.nt si.ze
((LONG)afmMetri.cs[i].sXDevi.ceRes == lxDevRes) /* compare X and Y Res
((LONG)afmMetri.cs[i.].sYDevl.ceRes == lYDevRes))/* for thi.s devl.ce

lLci.d = AllocatesetlD(hps): /* get a set l.d

if (1Lci.d!=GPI_ERROR) /* query PS codepage


uscodepage = Gpl.Querycp(hps); /* -ps handle

set font attri


fatAttrs.usRecordLength = si.zeof(FATTRS) record length
fatAttrs.fsselecti.on = 0; selecti.on flags
fatAttrs.IMatch = OL: match value
strcpy(fatAttrs.szFacename, afmMetri.cs[i.].szFacename); /* -facename
fatAttrs 1' d R e 9 i s t r y afmMetrl.cs[i.].i.dRegl.stry; /* -regi.stry l.d
fatAttrs uscodepage uscodepage: /* -codepage
fatAttrs 1 M a x 8 a s e 1 1. n e E x t afmMetri.cs[i.].IMaxBaseli.neExt;/* -max ble
fatAttrs l Avecha rwi dth afmMetri.cs[l.].1Avecharwl.dth; /* -ave chw
fatAttrs fsType /* -type flags
fatAttrs fsFontuse /* -font use flags

1.f (uscodepage!=GPI_ERROR) /* create logl.cal font */


fRet = Gpl.CreateLogFont( hps /* -PS handle */
(PSTR8)FONTNAME /* -font name */
lLcid /* -set id */
&fatAttrs /* -font attri.butes */
) !-GPI_ERROR;
break;
)
)
)

1 **************************************************************************** 1
/**/
/* Free the memory. */
/* If error set returned lci.d to GPI_ERROR. */
/**/
/ **************************************************************************** /

f ree ( afmMet ri. cs ) ;

1.f (!fRet || uscodepage==GPI_ERROR)


lLcl.d = GPI_ERROR;

return (lLcl.d);

Figure 4.4 (co7}££7?ztecz)


FONTS 115

crfmatch.c */
G CreateRasterFont_1Match(HPS hps)

Create a logi.cal font for a 12 pol.nt publl.c Couri.er raster font usl.ng
lMatch and return the set l.d (or GPI_ERROR for error).

i.nputs: hps PS handle

returns: LONG Set ID (Lci.d) of the newly created font (or GPI_ERROR)

#defi.ne P0INTSIZE 120


#defl.ne FACENAME "Courl.er"
#defl.ne FONTNAME "FONT01"

PFONTMETRICS afmMetri.cs = NULL /* pointer to FONTMETRICS array


LONG 1 NumFonts /* number of fonts avai.lable
LONG lRemFonts = GPI_ALTERROR /* number fonts not returned
LONG
LONG i !895R::s (: ::#:|r fo::;|.::q::s:i:t|.on
LONG 1 YDevRes /* actual Y devi.ce resolutl.on
B00L f Ret = FALSE /* B00L return code
HDC hdc = NULL /* DC handle
LONG ILcid = GPI_ERROR /* set l.d
INT 1 /* array 1.ndex
USHORT uscodepage = GPI_ERROR /* codepage
FATTRS fatAttrs /* font attri.butes
/,*.***************************************************************************/
_L
/*
/* Query the.number of fonts to determl.ne how much memory to allocate for
/Lr,

(: i:#sm##c:heal::::f:gt?:c::T::Y and query the m5tF'.`csioF';T'--5JbiT: :)


/* */
/****************************************************************************'/
1ReqFonts = OL;
/* Query Number of Fonts
lNumFonts = Gpl.QueryFonts( hps /* -PS handle
OF_PUBLIC /* -Optl.ons
FACENAME /* -facename
&1ReqFonts /* -number of fonts
OL /* -metrl.cs length
NULL /* -returned metrl.cs
n
I.f ((lNumFonts!=GPI_ALTERROR)&&(lNumFonts!= OL)) /* allocate memory for
afmMetri.cs = malloc((SHORT)(lNumFonts*si.zeof(FONTMETRICS))); /* metri.cs

I.fi#g:::I.±SG;=o|::;ionts( hps ;: 9;§r%a:8T: Metrl.CS

: 85i:!3bic ): ::g::::;e
&1NumFonts /* -number of fonts
(LONG)sl.zeof(FONTMETRICS) /* -metri.cs length
_ , L , , .

afmMetrl.cs /* -returned metric5


);

I,*****************************************************************************/

#Ouery the actual horizontal and vertical resolution for the device. :;
/****************************************************************************/
1.f (1RemFonts != GPI_ALTERROR)
hdc = Gpi.OueryDevice(hps); /* query associ.ated DC handle */

I.ff{::d±!;:#:#£#{=#:_ERRORH ): 9B:r%a:g::al devl.Ce x res

CAPS_HORIZONTAL_FONT_RES /* -fl.rst-1iem requested

&lLXDevRes (: :::#::e8fc:;9S requested


in

Figure 4.5 CreateRasterFont_lMatch Function.


116 OS/2 PRESENTATION MANAGER GPI

I.ff&:3e±)DevQuerycaps( hdc ): 9B:r%a:8f:al dev1.Ce Y res

CAPS_VERTICAL_FONT_RES /* -fl.rst 1.tern requested

: &lLyDevRes (: :::¥3::e8fc:;gs requested


in
I **************************************************************************** I
/**/
/* Search the font metrl.cs for a font that sati.sfl.es all of the followi.ng */
/* condl.tl.ons and create a logl.cal font for i.t usl.ng lMatch: */
/* font 1.s raster */

(; ::::ni:;:::t:::;i:::#r#i::n;::::i g::::: ::::]#::: ,::i:::fi)ly ;;


I **************************************************************************** I
l.f (fRet)
{ for (l. = 0; l. < (INT)lNumFonts; i.++) (: ::#T.:!r:::he::: :5:¥T.ne :(

(
1.f (!(afmMetri.cs[i.].fsDefn & FM_DEFN_OUTLINE) /* check for raster
&& !(strcmp(afmMetri.cs[i.].szFacename, FACENAME)) /* compare facename
&& (afmMetrl.cs[i.].sNoml.nalpol.ntsi.ze == P0INTSIZE)/* compare pol.nt si.ze
&& ((LONG)afmMetri.cs[i.].sXDevi.ceRes == lxDevRes) /* compare X and Y Res
&& ((LONG)afmMetrl.cs[1.].sYDevl.ceRes == lYDevRes))/* for thl.s devl.ce
(
1Lci.d = AllocatesetlD(hps); /* get a set 1.d
I.fu!::::i:;:P±i§i§5:rycp(hps) ; ): 9;:r%a:§T:°depage

/* set font attri.butes


f::A:#§:¥§§:i::€,I::gth = 8l;Ze°f(FATTRS): ): :::i::8T.::n#:gs
fatAttrs.IMatch = afmMetri.cs[i.].1Match:/* -match value
strcpy(fatAttrs.szFacename, afmMetrl.cs[i.].szFacename); /* -facename
fatAt,trs.1.dRegl.stry = afmMetri.cs[i.].idRegl.stry; /* -regi.stry 1.d
fatAttrs.uscodepage = uscodepage; /* -codepage
fatAttrs.IMaxBaseli.neExt = OL: /* -max ble
fatAttrs.1Avecharwi.dth = OL; /* -ave chw

f::A:#::f:F#:use : 8; (: ::#: :::gi|ags


if (uscodepage!=GPI_ERROR) /* create logi.cal font
fRet = Gpi.CreateLogFont( /* -PS handle
STR8 ) FONTNAME /* -font name
/* -set l'd
&fatAttrs /* -font attri.butes
!-GPI_ERROR
break:
)
)
)

/ **************************************************************************** 1
/**/
/* Free the memory. */
/* If error set returned lci.d to GPI ERROR. */
/**/
1 **************************************************************************** I
f ree ( afmMet ri. cs ) ;
l'f (!fRet uscodepage==GPI_ERROR)
1 Lcl.d - in I_ERROR :
return (1Lcl.d);

Figure 4.5 (co7i££7}t/ecg)


FONTS 117

crtolfnt.c */
G Createoutli.neFont (HPS hps)

Create a logi.cal font for a Courl.er Bold outll.ne font wl.thout


usi.ng lMatch and return the set i.d.

i.nputs: hps PS handle

returns: LONG Set ID (Lcl.d) of the newly created font


or GPI ERROR for error or not found

#defi.ne FACENAMEB "Couri.er Bold'.


#defi.ne FONTNAME "FONT01"

PFONTMETRICS afmMetri.cs = NULL /* pol.nter to FONTMETRICS array


LONG I NumFonts /* number of fonts
LONG 1 ReqFonts /* number fonts requested
LONG IRemFonts = GPI ALTERROR /* number fonts not returned
B00L fRet = FALSE /* B00L return code
HDC hdc = NULL /* DC handle
LONG ILci.d = GPI_ERROR /* set l'd
INTI /* array index
USHORT uscodepage = GPI_ERROR /* codepage
FATTRS fatAttrs /* font attributes

1 **************************************************************************** I
/**/
/* Query the number of fonts to determl.ne how much memory to allocate for */
/* font metrl.cs, allocate the memory and query the metrl.cs for all publl.c */
/* fonts wl.th the requl.red facename. */
/**/
/ **************************************************************************** /

1ReqFonts = OL; /* Query Number of Fonts


lNumFonts = Gpi.QueryFonts( hps /* -PS handle
QF_PUBLIC /* -Optl.Ons
FACENAMEB /* -facename
&lReqFonts /* -number of fonts
OL /* -metri.cs length
NULL /* -returned metri.cs
);

i.f ((1NumFonts!=GPI_ALTERROR)&&(1NumFonts!= OL)) /* allocate memory for


afmMetri.cs = malloc((SHORT)(lNumFonts*si.zeof(FONTMETRICS))); /* metri.cs

i.f (afmMetrl.cs != NULL) /* query Font Metri.cs


1RemFonts = Gpl.QueryFonts( hps /* -PS handle
QF_PUBLIC /* -Optl'ons
. FACENAMEB /* -facename
&1NumFonts /* -number of fonts
(LONG)si.zeof(FONTMETRICS) /* -metri.cs length
afmMetrl.cs /* -returned metrl.cs
in

Figure 4.6 CreateoutlineFont Function.


118 OS/2 PRESENTATION MANAGER GPI

1 **************************************************************************** 1
/**/
/* Search the font metrl.cs for a font that sati.sfies the followi.ng */
/* condi.ti.ons and create a logi.cal font for i.t wl.thout usi.ng lMatch: */
/* font i.s outline */
/* facename matches requi.red facename */
/**/
/ **************************************************************************** /

i.f (lRemFonts != GPI_ALTERROR)


{ /* step through and exami.ne */
for (I. = 0: i < (INT)1NumFonts: 1.++) /* metri.cs of each font */

((afmMetrics[i.].fsDefn & FM_DEFN_OUTLINE) /* check for outll.ne */


!(strcmp(afmMetri.cs[i.].szFacename, FACENAMEB)))/* compare facename */

lLcl.d = AllocatesetlD(hps): /* get a set ltd */

if (lLci.d!=GPI_ERROR) /* query PS codepage */


uscodepage = Gpl.Querycp(hps): /* -ps handle */

font attrl.
fatAttrs.usRecordLength = sl.zeof(FATTRS) record length
fatAttrs.fsselectl.on = 0: selecti.on flags
-match value
fatAttrs . I Match
s t rcpy ( f atAtt rs . s z Fa cen ame afmMetri.cs[i.].szFacename): /* -facename
fatAttrs i d R e a 1' s t r y afmMetri.cs[l.].i.dRegl.stry: /* -regl.stry i.d
fatAttrs uscodepage uscodepage: /* -codepage
fatAttrs 1 M a x 8 a s e 1 i. n e E x t OL: /* -max ble
fatAttrs 1 A v e C h a r W i. d t h OL; /* -ave chw
fatAttrs fsType 0; /* -type flags
fatAttrs fsFontuse ( FATTR_FONTUSE_OUTLINE /* -font use
I FATTR_FONTUSE_TRANSFORMABLE) ;

if (uscodepage!=GPI_ERROR) /* create logical font


fRet = Gpl.CreateLogFont( hps /* -PS handle
(PSTR8)FONTNAME /* -font name
lLcl'd /* -set l'd
. &fatAttrs /* -font attri.butes
) !-GPI_ERROR:
break:
)
)
)
/ **************************************************************************** I
/**/
/* Free the memory and return. */
/**/
1 **************************************************************************** I

f ree( afmMetri cs ) ;

1.f (!fRet || uscodepage==GPI_ERROR)


1 Lci.d = GPI_ERROR;

return (lLcl.d):

Figure 4.6 (co7i££7}zJecz)


FONTS 119

allocset.c */
NG AllocatesetlD (HPS hps)

Return an unused set id (Lcl.d) or GPI_ERROR for error (or none aval.1able).

i.nputs: hps Ps handle

returns: LONG unused set 1.d (Lci.d)

#defi.ne MAXSETID 254L

INTI /* INT array 1.ndex


LONG ILcl.d = GPI_ERROR /* returned set i.d
LONG ICount /* returned number of set i.ds
B00L fRet = FALSE /* B00L return code
PLONG alLci.ds = NULL /* returned set l.d poi.nter
PLONG alTypes /* returned type pol.nter
PSTR8 aNames /* returned names poi.nter

lcount = Gpl.QueryNumbersetlds(hps): /* query the number of set l.ds*/

l'f (lcount--0) /* l.f number set i.ds l.s zero */


return( 1L) ; /* set return set i.d to 1 */

I.f (lcount!=GPI_ALTERROR)
(
alLci.ds = malloc((SHORT)(16 * 1Count)) /* allocate memory for
alTypes = (PLONG)(alLcids + lcount); /* set l.ds, types and
aNames = (PSTR8)(alTypes + lcount): /* names

1.f (alLci.ds!=NULL) /* query set i.ds


fRet = Gpi.Querysetlds( hps /* -PS handle
lcount /* -number set i.ds queri.ed
alTypes /* -returned types
aNames /* -returned names
alLcl'ds /* -returned set l.ds
in

/* step through range of


/* vali.d set I.ds searchi.ng
1.f (fRet) /* returned set i.d array fo
( /* an unused value
for (1Lci.d=1; 1Lcl.d<(MAXSETID+1); lLci.d++)
(
for (I.=0; (I.<(INT)lcoHnt) && (alLci.ds[i.]!=lLci.d); I.++);

l.f (i.==(INT)1Count) /* I.f unused value found */


break ;
)
1.f (lLcid==MAXSETID+1)
lLcl.d = GPI_ERROR;
)
f ree( al Lci ds ) ;
)
r e t u r n ( 1 L c 1. d ) ; /* return the set i.d */

Figure 4.7 AllocatesetlD Function.


120 OS/2 PRESENTATION MANAGER GPI

setolpsz.c */
L Setoutli.neFontpol.nts1.ze( HPS hps, LONG 10utll.neLcl.d)

Set the character set to the speci.fi.ed outli.ne font set I.d and set the
character box attri.bute to gl.ve the outll.ne font the requi.red poi.nt sl.ze.
Note that thl.s functi.on i.s i.ntended to handle outll.ne fonts desl.gned 1.n a
square space wi.th sXDevi.ceRes and sYDevi.ceRes equal (thi.s 1.s true for all
Presentati.on Manager fonts that are not devl.ce fonts).

I.nputs: hps Ps handle


10utli.neLci.d Outli.ne font set 1.d

#defi.ne p0INTSIZE 10L


#defl.ne p0INTSPERINCH 72L

HDC hdc ; /* DC handle


B00L fRet = FALSE : /* B00L return code
LONG IYDevResFont : /* verti.cal devl.ce resolutl.on for font selectl.on
P0INTL aptlpoi.nts[2] ; /* poi.nt array
SIZEF si.zfxcharBox : /* character box si.ze
LONG IPoi.ntsi.zelnpels ; /* poi.nt si.ze i.n pels
LONG IPoi.ntsizelnwc : /* pol.nt sl.ze l.n world coordi.nates

/ ****************************************************************************** 1
/**/
/* Query verti.cal devl.ce resoluti.on for font selectl.on. */
/**/
/ ****************************************************************************** 1

hdc = Gpl.QueryDevice(hps); /* query the DC handle


I.f ((hdc != NULL) && (hdc != HDC_ERROR)) /* query caps
fRet = DevQuerycaps( hdc /* -DC handle
CAPS_VERTICAL_FONT_RES /* -fl.rst 1.tern
1L /* -count of I.terns
&1YDevResFont /* -returned resoluti.on
n
1 ****************************************************************************** /
/**/
/* Calculate requi.red point si.ze in pels rounded up to the nearest pel and */
/* convert to world coordl.nates. */
/**/
/ ****************************************************************************** /

lpoi.nts1.zelnpels = ((1YDevResFont*P0INTSIZE+(P0INTSPERINCH/2))/P0INTSPERINCH):

aptlpoi.nts[0].x = OL:
aptlpoi.nts[0].y = 1L:
aptlpoi.nts[1].x = OL:
aptlpol.nts[1].y = 1Poi.ntsizelnpels+1;
i.f (fRet) /* convert coordi.nates
fRet = Gpi.Convert( hps /* -PS handle
CVTC_DEVICE /* - source
CVTC_WORLD /* -target
2L /* -count
aptlpoi.nts /* -coordi.nate array
in
lpol.ntsi.zelnwc = aptlpoints[1].y -aptlpol.nts[0].y:

Figure 4.8 SetoutlineFontpointsize Function.


FONTS 121

/****************************************************************************** I
/**/
/* set the character set to the outll.ne font set i.d */
/* set the character box dl.mensl.ons to the pol.nt sl.ze l.n world coordi.nates */
/* converted to FIXED (l..e. tl.mes Oxl0000). */
/**/
1****************************************************************************** I

l.f (fRet) /* set char set


fRet = Gpi.Setcharset( hps /* -PS handle
10utli.neLci.d /* -set l'd
in

si.zfxcharBox.cx = lpoi.ntsi.zelnwc*Oxl0000;
si.zfxcharBox.cy = lpol.ntsi.zelnwc*Oxl0000:

1.f (fRet) /* set char box


fRet = Gpi.SetcharBox( hps /* -PS handle
&si.zfxcharBox /* -character box
);

return ( fRet ) ;

Figure 4.8 (continued)

sclolfx.c */
L Scaleoutli.neTOFi.xed (HPS hps, LONG loutll.neLcl.d, LONG IRasterLcl.d)

Set the character set to the specl.fi.ed outli.ne font 1.d and set the
character box attrl.bute to gl.ve an outli.ne font the same si.ze as the
speci.fi.ed raster font (any remai.ni.ng vi.sual di.fferences ari.se from
di.fferences 1.n font desi.gn).

inputs: hps Ps handle


loutlineLcl.d Outll.ne font set l.d
lRasterLcl.d Raster font set 1.d

B00L fRet /* B00L return code


FONTMETRICS fmRMetri.cs /* raster font metri.cs
SIZEF si.zfxcharBox /* character box sl.ze

/*********************+******************************************************** I
/**/
/* set the character set to the raster font set 1.d */
/* query the font metrl.cs for the raster font */
/* set the character set to the outli.ne font set I.d */
/* set the outli.ne font character box attrl.bute di.mensi.ons to the lEmHei.ght */
/* lEmlnc metri.c values for the raster font */
/**/
/ ****************************************************************************** 1

/* set raster font char set */


Figure 4.9 ScaleoutlineTOFixed Function.
122 OS/2 PRESENTATION MANAGER GPI

fRet = Gpi.Setcharset( hps /* -PS handle


lRasterLcl.d /* -set l'd
in
1.f (fRet) /* query font metrl.cs
fRet = Gpi.OueryFontMetri.cs( hps /* -PS handle
(LONG)si.zeof(FONTMETRICS) /* -metri.cs length
&fmRMetri.cs /* -returned metri.cs
):

1'f (fRet) /* set outli.ne font char set


fRet = Gpi.Setcharset( hps /* -PS handle
10utll.neLcl.d /* -set l'd
in

si.zfxcharBox.cx = MAKEFIXED(fmRMetrics.1EmHeight,0);
si.zfxcharBox.cy = MAKEFIXED(fmRMetri.cs.IEmlnc,0);

l'f (fRet) /* set char box */


fRet = Gpi.SetcharBox( hps /* -PS handle */
&sl.zfxcharBox /* -char box sl.ze */
in
return ( fRet ) ;

Figure 4.9 (co7}£Z7}zJecz)

sclolfx2.c */
L Scaleoutli.neTOFixed2( HPS hps, LONG loutll.neLci.d, LONG IRasterLci.d)

Set the character set to the speci.fi.ed outli.ne font l.d and set the
character box attri.bute to gi.ve an outli.ne font the same sl.ze as the
specl.fl.ed raster font. The character box l.s set to a value that scales
the lxHel.ght metrl.c of the outll.ne font to match that of the raster
font (any remai.ni.ng vi.sual di.fferences ari.se from di.fferences l.n font
d e s 1. 9 n ) .

1.nputs: hps Ps handle


loutll.neLci.d Outll.ne font set 1.d
lRasterLci.d Raster font set l.d

B00L fRet /* B00L return code


FONTMETRICS fmRMetri.cs /* raster font metri.cs
FONTMETRICS fmoMetrl.cs /* outli.ne font metri.cs
SIZEF sl.zfxcharBox /* character box sl.ze

/ ****************************************************************************** 1
/**/
/* set the character set to the raster font set l.d */
/* query the font metrl.cs for the raster font */
/* set the character set to the outli.ne font set i.d */
/* set the character box attri.bute di.mensi.ons to a known value (1000xl000) */
/* query the font metri.cs for the outli.ne font */
/* change character box di.mensi.ons to scale lxHei.ght for the outli.ne font to */
/* match that of the raster font and set the new character box attri.bute. */
/**/
/ ****************************************************************************** 1

Figure 4.10 ScaleoutlineTOFixed2 Function.


FONTS

/* set raster font char set


fRet = Gpi.Setcharset( hps /* -PS handle
lRasterLci.d /* -set l'd
in

l'f (fRet) /* query font metri.cs


fRet = Gpl.QueryFontMetrl.cs( hps /* -PS handle
(LONG)sl.zeof(FONTMETRICS) /* -metri.cs length
&fmRMetri.cs /* -returned metri.cs
);

l'f (fRet) /* set outll.ne font char set


fRet = Gpl.Setcharset( hps /* -PS handle
10utli.neLci.d /* -set l'd
n
si.zfxcharBox.cx = Ox3E80000:
sl.zfxcharBox.cy = Ox3E80000;

l'f (fRet) /* set char box


fRet = Gpi.SetcharBox( hps /* -PS handle
&sizfxcharBox /* -set l'd
n
l'f (fRet) /* query font metrl.cs
fRet = Gpl.QueryFontMetri.cs( hps /* -PS handle
(LONG)sl.zeof(FONTMETRICS)/* -metrl.cs length
&fmoMetri.cs /* -returned metri.cs
in

sl.zfxcharBox.cy = sl.zfxcharBox.cx
= ( Ox03E80000/fmoMetri. cs .1 XHei. ght )*fmRMetrl. cs . I XHel. ght :

l'f (fRet) /* set character box


fRet = GpisetcharBox( hps /* -PS handle
&sizfxcharBox /* -char box si.ze
in
return ( f Ret ) :

Figure 4.10 (co7?££7}z/ecz)


124 OS/2 PRESENTATION MANAGER GPI

setpl'tch.c */
L SetHorl.zontalpi.tch(HPS hps, LONG loutli.neLci.d, LONG Ipi.tch)

Set the character set to the speci.fi.ed outll.ne font l.d and set the
character box attri.bute to provi.de the speci.fi.ed hori.zontal pi.tch i.n
characters per i.nch.

I.nputs: hps Ps handle


10utll.neLcl.d Outll.ne font set i.d
lpi.tch requl.red hori.zontal pi.tch l.n characters to l.nch

B00L fRet = FALSE B00L return code


FONTMETRICS fmoMetri.cs outli.ne font metri.cs
SIZEF sl.zfxcharBox character box sl.ze
LONG IXResoluti.on hori.zontal resoluti.
LONG IAvecharwi.dth average char wi.dth
P0INTL aptlpoi.nts[2] coordi.nate pol.nt
HDC hdc DC handle

I ****************************************************************************** 1
/**/
/* query the devi.ce resoluti.on */
/* set the character set to the outli.ne font set l.d */
/* set the character box attri.bute di.mensi.ons to a known value (1000xl000) */
/* query the font metrl.cs for the outli.ne font */
/* convert the Avecharwi.dth to devi.ce coordi.nates (pels) */
/* calculate the new character box to gi.ve the requi.red pl.tch */

)= #:XF;:::T=t{:i;::€:idi:/:::t#:::Wi:t:i:X::;°:#:::P::::acter wi.dth :)
/* The char box 1.s thus scaled by the rati.o NewAvecharwi.dth/OldAvecharwi.dth */
/* set the new character box attri.bute
*/
/**/
/****************************************************************************** I

/* query the DC handle */


hdc = Gpl.QueryDevice( hps ); /* -PS handle */

I.f ((hdc!=NULL)&&(hdc!=HDC_ERROR)) /* query the resolutl.on


fRet = Devouerycaps( hdc /* -DC handle
CAPS_HORIZONTALRESOLUTI0N /* -fl'rst l'tem
1L /* -count
&lxResoluti.on /* -returned resoluti.on
);

lxResoluti.on = lxResoluti.on*Oxl0/Ox276; /* convert from pels per


meter to pels per i.nch */

1' f ( f R e t ) /* set outli.ne font char set


fRet = Gpi.Setcharset( hps /* -PS handle
10utli.neLci.d /* -set l'd
n
si.zfxcharBox.cx = Ox3E80000:
si.zfxcharBox.cy = Ox3E80000;

l'f (fRet) /* set char box


fRet = Gpi.SetcharBox( hps /* -PS handle
&si.zfxcharBox /* -set l'd
in

Figure 4.11 SetHorizontalpitch Function.


FONTS 125

1.f (fRet) /* query font metri.cs


fRet = Gpi.QueryFontMetri.cs( hps /* -PS handle
(LONG)sl.zeof(FONTMETRICS)/* -metrl.cs length
&fmoMetri.cs /* -returned metri.cs
);

aptlpoi.nts[0].x = OL; /* convert average


aptlpol'nts[0].y -OL; /* character wl.dth to
aptl Pol. nts [1 ] . x = fmoMetri. cs . I Avecharwi. dth ; /* devi.ce coordi.nates
aptlpoi.nts[1].y = OL:
l'f (fRet)
fRet = Gpl.Convert( hps
CVTC_WORLD
CVTC_DEVICE
2L
aptlpoints p 0 1. n t s
n
lAvecharwl.dth = aptlpoi.nts[1].x -aptlpoi.nts[0].x;

/* scale character box to g1.ve the requl.red pl.tch */

si.zfxcharBox.cy = si.zfxcharBox.cx
= ( ( Ox03E80000/1 P1. tch )*1 XResol utl. on ) /1 Avecharwi. dth ;

1'f (fRet) /* set character box


fRet = Gpi.SetcharBox( hps /* -PS handle
&si.zfxcharBox /* -char box si.ze
in

retu rn ( f Ret ) ;

Figure 4.11 (con££71ztecz)


Bitmaps

A bitmap is a rectangular array of color or monochrome pixel data held in PC or


device memory. It is used for the rapid transfer of rectangular blocks of pixel data
between bitmaps and raster devices (or other bitmaps). Such operations are called
Bit Block 'Thansfer or BitBlt operations.
Bitmaps are device dependent ob].ects and every bitmap must at all times be
owned by (and be compatible with) some device, although it is possible to change
ownership of a bitmap to a different device. In order to perform a BitBlt operation,
both the source and target of the BitBlt operation must be owned by the same
device.
See chapter 3 for a description of BitBlt drawing primitives.

BITmAp FORMATs

Bitmap formats are specified as the number of color planes and number of bits per
pel. Standard bitmap formats are all defined with only a single plane and one or
more bits per pel but this is only a convention. It is equally valid to describe the
same bitmap as having one plane with eight bits per pel or eight planes with one
bit per pel. The standard bitmap formats are as follows:
• A single plane with 1 bit per pel (i.e., monochrome).
• A single plane with 4 bits per pel (i.e., 16 color).
• A single plane with 8 bits per pel (i.e., 256 color).
• A single plane with 24 bits per pel (i.e., RGB).

A presentation driver must allow bitmap creation in any of the four standard
formats as well as in any non-standard internal device formats of its own.
Although drivers must allow bitmap creation in the standard formats, it is not

i26
BITMAPS IZ]

essential for these formats to be supported intermally. For formats not supported
intemally, the driver will select its most appropriate internal device format and
perform the necessary conversion of bitmap initialization data. In addition, all
drivers must be capable of supporting bitmap data conversion between any of the
standard formats and any internal device format. This is to allow bitmap data in
any standard format to be transferred between application memory and a bitmap
(in either direction) using GpicreateBitmap, GpisetBitmapsBits, and
GpiQueryBitmapBits.
Bitmap formats supported intermally by a driver, where the first format re-
turned is that which most closely matches the device, can be queried using:

GpiQueryDeviceBitmapFormats.

The driver is entitled to modify bitmap initialization data in the process of


converting it to internal format as follows:

• Color table information provided (in a BITMAPINFO structure) with


bitmap initialization data on GpicreateBitmap or GpisetBitmapBits
may be remapped to the nearest available device color.
•Where the intermal device bitmap form.at has fewer bits per pel
than the data, loss of information may occur. For example, a
monochrome printer will normally support only monochrome
bitmaps inter'nally and will therefore remap all colored bitmap data
to black and white.
• Where device background and foreground bitmap colors do not match
the color table of the bitmap data, inversion of the bitmap bits and
reversal of the color table may occur. This was a fairly serious
problem when printing monochrome display bitmaps with some of
the early printer drivers but the driver interface specification has
since been clarified and the problem is now largely corrected for most
drivers (at the time of writing a few inconsistencies remain, however,
for bitmaps initialized by drawing to a monochrome printer bitmap
and for transferring colored bitmaps from a color display to a mono-
chrome printer).

These effects will generally be apparent from an examination of BitBlt output or


of the bitmap data returned from GpiQueryBitmapBits.
Note that even where an application has not created its own logical color table,
bitmaps are not restricted to the 16 colors in the standard color table but have
access to the entire range of colors available in the device palette. Where
GpiRealizecolorTable is supported and a realizable color table has been created,
bitmaps have access to the full range of realized colors regardless of whether the
color table is actually realized when the bitmap contents are initialized. These
realized colors will, of course, only be displayed coITectly if the target PS (of a
BitBlt operation) has same color table that is also realized (see below).
1T8 0S/2 PRESENTATION MANAGER GPI

BITMAP CREATION AHD DELETION

Bitmaps are created and deleted using the functions described below:

GpicreateBitmap

This creates a new bitmap of specified dimensions and format and optionally
initializes it. The bitmap dimensions theight, width) and format ®lanes, bits per
pel) are specified in a BIThVIAPINFOHEADER structure parameter. The format of
the bitmap initialization data may be different froln that of the bitmap and is
described by a separate BI'IMAPINFO structure parameter. The BI'IT\IAPINFO
structure is the same as a BI'IT\IAPINFOHEADER structure except that for
bitmap formats other than 24 bits per pel, it is followed by an alTay of color table
information describing the color represented by each combination of bits. This
color table will contain 2"n entries where n is the number of bits per pel. The
length of the bitmap initialization data may exceed 64K bytes.
For certain devices (e.g., 8514/A) bitmap creation in device internal format may be
considerably faster if the bitmap color table exactly matches that of the device
palette (this can be determined using GpiQueryRealcolors).

GpiLoadBitmap

This creates and loads a bitmap from a resource file and returns the bitmap
handle. The bitmap will typically have been originally created using the iconedit
utility and compiled with the resource compiler. The rc file will typically contain a
statement of the form:
BITMAP ID_BITMAP3 mybmap.bmp
where ID_BI'ITVIAP3 is a numeric constant (e.g., #define ID_BI'IMAP3 3) for the
bitmap ID to be specified with GpiLoadBitmap, and mybmap.bmp is the name of
the bitmap file created by iconedit. The compiled bitmap resource (res) file may be
added to the application exe file using the resource compiler or included in a DLL
resource file and loaded using DosLoadModule.
GpilloadBitmap specifies the height and width of the required bitmap and,
where these differ from the values in the resource file, stretching or compression
of the bitmap data will occur. Either or both dimensions may be specified as zero
on GpilioadBitmap causing the original value or values to be used unchanged (i.e.,
with no stretching or compression).

WinLoadpointer

This loads a pointer or icon (see below) from a DLL resource file and returns its
handle.
BITMAPS 129

GpiDeleteBitmap

This deletes the specified bitmap.

BITMAP SELECTION

A bitmap may be used as the source or target of a BitBlt operation, or used as the
target of any valid drawing operation. In order to draw to a bitmap, use it as the
target of a GpiwcBitBlt operation, source, or target of GpiBitBlt, the bitmap must
be selected into an OD MEMORY DC associated with a PS.
Also, in order to tran-sfer bitmap ownership from one device to another, it must
be deselected from the Psroc for the old device (if selected) and then selected into
a PS associated with an OD MEMORY DC for the new device. This is accom-
plished as follows:
GpisetBitmap(hpsold, NULL); /* deselect from existing ps
(if selected) */
GpisetBitmap®psNew, hbitmap); /* select to PS/OD MEMORY
Dcfornewdevi;e */
Note that GpiwcBitBlt does not require its source bitmap to be selected into a
Psroc, although it must be owned by the target device. If GpisetBitmap is used
to transfer bitmap ownership, the bitmap should then be deselected from the new
device before GpiwcBitBlt is issued. Note also that bitmap ownership by a device
will continue after the bitmap has been deselected from its Psroc until it is
selected to a Psroc for a different device.

BITMAP DATA FORMAT AND DATA TRANSFER

Data can be transferred between a bitmap and application memory using:


GpisetBitmapBits; and
GpiQueryBitmapBits.
Both of these functions include a BITMAPINFO parameter. In the case of
GpisetBitmapBits, this specifies the size and format of the data to be transferred
together with its color table. In the case of GpiQueryBitmapBits, only certain of
the BI'IT\IAPINFO fields are required as inputs, the remainder being part of the
returned data. The number planes and number of bits per pel (i.e., cplanes and
cBitcount) must be specified on input, whereas the height, width, and color table
(i.e., cx, cy, and argbcolor) are returned. In all cases involving the BITMAPINFO
and BITMAPINFOHEADER stmctures, the length field (cbFix) should be initial-
ized by the application.
As mentioned earlier, the formats specified with these functions may differ from
the actual bitmap format used intemally and may also differ from the format
130 OS/2 PRESENTATION MANAGER GPI

originally specified when the bitmap was created. Conversion is performed as


necessary by the system.
An example of the format of bitmap data and its BIu\IAPINFO structure used
by these functions and for bitmap initialization is illustrated in Figure 5-1. A
BITMAPINFOHEADER stmcture is the same as the BITMAPINFO stmcture
shownwithoutthecolortable.Notethatthebitsarepackedlefttorightinadjacent
bits of adjacent bytes with the most significant bits of each byte representing the
leftmost pels and the data starting with the bottom row of pels and working
upward. Each row is padded to the nearest 4 byte boundar'y. The memory require-
ment for a single scanline can therefore be determined by:
(®itcount * bitmapwidth + 31y32) * planes * 4 bytes
As well being stored in DLL resource files and, in the case of bitmaps, application
exe files, bitmaps, icons, and pointers may also be stored in their own bmp, ico,
and ptr files. Such files are typically created using the iconedit utility. The file
begins with one or, for color icons and pointers, two BITMAPFILEHEADER or
BITMARARRAYFILEHEADER structures (defined in PMBITMAP.H) identifying

SAMPLE 5x3 BITMAP

Pels
top row: red green blue red green
blue red green blue red
green blue red green blue

BYTE Bi.tmapData[12] = { OxA9, OxCA, Ox90, OxOO /* bottom l1.ne */


Ox9C, OxA9, OxCO, OxOO /* mi.ddle line */
OxCA, Ox9C, OxAO, OxOO /* top 11.ne */
in

BYTE Bi.tmaplnfo = { OxOC, OxOO, OxOO, OxOO /* cb fi.xed porti.on


Ox05, OxOO /* wl.dth cx = 5
Ox03, OxOO /* hei.ght cy = 3
OxO1, OxOO /* cplanes =1
. Ox04. OxOO /* cBi.tcount = 4
OxOO, OxOO /* (0) black
0x80, OxOO /* (1) dark blue
0xOO, Ox80 /* (2) dark green
0x80, Ox80 /* (3) dark cyan
0xOO, OxOO /* (4) dark red
0x80, OxOO /* (5) dark pi.nk
0xOO, Ox80 /* (6) brown
0x80, Ox80 /* (7) pale gray
0x20, Ox20 /* (8) dark gray
0xFF, OxOO /* (9) blue
0xOO, OxFF /* (A) green
0xFF, OxFF /* (a) cyan
0xOO, OxOO /* (C) red
0xFF, OxOO /* (D) pl'nk
0xOO. OxFF /* (E) yellow
OxFF /* (F) whl'te

Figure 5.1 Bitmap Data Format Example.


BITMAPS 131

the type of image (as a bitmap, icon, pointer, color icon, or color pointer), the
hotspot position for icons and pointers, and an offset to the bitmap data in the
format described above. Icons and pointers both have the same format and, for
monochrome icons and pointers, the file contains a double height bitmap providing
XOR and AND masks. The AND mask determines whether the screen or
icon/pointer is displayed in each pel position (0 specifies display icon/pointer, 1
display screen) and the XOR mask determines whether or not each bit of the
resulting image must be inverted (i.e., black/white or screen/inverse screen). For
colored icons and pointers, a second bitmap defining the color content is provided.
In this case, a one bit in the XOR mask will invert the screen but leave the
icon/pointer color unchanged. The bitmap file format is described in the IBM OSA
FTogramming Reference.
Icons and pointers may be created (using the iconedit utility) in device indepen-
dent format, in which case the file will contain an array of different versions of the
icon or pointer to match each of the different device resolutions.
In order to print an icon or pointer, it can be loaded using WinLoadpointer, and
WinQuerypointerlnfo can then be used to obtain a POINTERINFO structure. This
contains handles for the two (double height XOIVAND and color) component
bitmaps. The double height bitmap must then be separated into its two parts and
the appropriate BitBlt Rop mix values applied. Because of inversion inconsisten-
cies in handling monochrome bitmaps some older print drivers may require
slightly different Rop mix values.

BITMAP DIMEHSIOH FUHCTIOHS

'two rather uninteresting functions exist for storing and retrieving a width and
height to and from a bitmap. These are:
Gpis etBitmapDimension; and
GpiQueryBitmapDimension.
These functions were included for reasons of compatibility with earlier products.
They exist for application convenience only and the data set by
GpisetBitmapDimension does not in any way affect the bitmap. It is stored with
the bitmap solely to enable it to be subsequently retrieved. These functions could,
in fact, be used to store any user data with the bitmap.

BITMAP AND BITBLT EXAMPLES

Bitmap and BitBlt operations are illustrated in the following examples.


The function CreateBitmap in Figure 5-2 illustrates bitmap creation using
GpicreateBitmap and initialization of the bitmap by making it the target of
normal Gpi drawing operations. The DC handle parameter specifies the device for
which the bitmap is to be created and may be specified as NULL for a display
132 OS/2 PRESENTATION MANAGER GPI

device. It is interesting to note that, for a display at least, when a monochrome


bitmap is erased its bits are set to all ones and drawing causes the bits to be set to
zero. Note also that when drawing to a bitmap using page units other than
PU PELS for a device (e.g., a printer) that supports a number of different
resJlutions, the dimensions of the image may be incoITect unless the default
resolution for the device is used. This is because devices are cuITently unable to
determine the correct resolution to use for an OD_MEMORY DC (see Appendix 1).
The function BitBlt in Figure 5-3 illustrates the use of GpiBitBlt, including
creation of the required PS and OD_MEMORY DC, and bitmap selection using
GpisetBitmap. Note that this entire function could be replaced by a single
GpiwcBitBlt call assuming the source bitmap was initially owned by coITect
target device.
The function WCBltTonrinter in Figure 54 illustrates the transfer of bitmap
ownership from the display to a printer (say), and the use of GpiwcBitBlt to
perfo]rm a BitBlt operation to the printer. Here a PS and OD_MEMORY DC are
created, and bitmap selection is performed using GpisetBitmap, solely for the
purpose of transferring bitmap ownership. The bitmap is then deselected from the
Psroc before issuing GpiwcBitBlt. Note that, assuming the page units are
PU PELS and all transforms are set to identity, the GpiwcBitBlt source rectangle
dim-ensions must be one larger than the corresponding target rectangle dimen-
sions in order for the true source and target rectangles to be identical. This is
because the source rectangle is specified in device coordinates that are exclusive
at two boundaries whereas the target rectangle is specified in world coordinates
that are inclusive at all four boundaries.
The function WCBltLoadedBitmap in Figure 5-5 illustrates the use of
GpiLoadBitmap to load and create a bitmap followed by GpiwcBitBlt to performi
a BitBlt operation.
Finally, the function Realizecolorlmage in Figure 5no illustrates the use of a
realizable color table for displaying a colored bitmap image. A bitmap is first
created and selected into a PS associated with an OD MEMORY DC and a
realizablecolortablecontainingthebitmapcolorinformati;niscreatedfortheps,
but not realized. This must occur before initializing the bitmap contents with the
image data. The same realizable color table is then both created and realized for
the display PS before GpiBitBlt is issued to display the image. Note that if the
bitmap is held in a bmp file, it is necessary to open the bitmap file and access the
bitmap color information in order to use the realize functions.
BITMAPS 133

/* crbi.tmap.c */
HBITMAP CreateBl.tmap(HAB hab, HDC hdc)
(
/* Create a bi.tmap for the specifl.ed devl.ce and draw to i.t. Return the bi.tmap
/* handle or GPI_ERROR.
/*
/* i.nputs: hab anchor block handle
/* hdc DC handle i.denti.fyi.ng the devi.ce for whi.ch the bi.tmap i.s
/* to be created (can be NULL for the di.splay)
/*
/* returns: HBITMAP bi.tmap handle or GPI_ERROR on error
/*

#defi.ne BMAPWIDTH 200


#defi.ne BMAPHEIGHT 100
#defi.ne BMAPPLANES 1
#defi.ne BMAPBITCOUNT 1
"Thi.s I.s a Bl.tmap"
#define BMAPCHARS
#defl.ne NBMAPCHARS ( LONG ) ( s I. zeof ( BMAPCHARS ) -1 )

BITMAPINFOHEADER bmplnfoHdr /* bl.tmap l.nfo header


SIZEL s 1' z 1 P S /* PS page si.ze
P0INTL ptl Posn /* coordi.nate pol.nt
HDC hdcMem /* OD MEMORY DC handle
HBITMAP hbm GPI_ERROR : /* bi.tmap handle
HPS hps GPI_ERROR : /* PS handle
HBITMAP hbmr HBM_ERROR ; /* Gpi.SetBi.tmap return code
B00L fRet FALSE : /* B00L return code

b in p I n f o H d r . c b F i. x s 1. z e o f ( 8 I T M A P I N F 0 H E A D E R )
bmp I nfoHd r . cx BMAPWIDTH ;
bmp I nfoHd r . cy BMAPHEIGHT ;
bmplnfoHdr . cpl anes BMAPPLANES ;
b in p I n f o H d r . c 8 1. t C o u n t BMAPBITCOUNT :

hdcMem = DevopenDC( hab /* create OD_MEMORY DC for display


OD_MEMORY /* -DC type
* ,, /* -token
OL /* -DEVOPENDATA count = 0
NULL /* -DEVOPENDATA (not requi.red)
hdc /* -devl.ce DC handle
in

s I. zl PS . cx=0 : /* set PS di.mensl.ons = zero (default) */


s ,I z 1 P S . cy-0 ;
I.f (hdcMem!=DEV_ERROR) /* create PS and associ.ate
hps = Gpl.Createps( hab /* -anchor block handle
hdcMem /* -hdc
&sl`ZIPS /* -sl'ze
PU_PELS /* -optl`ons
G P I F_D E FAU LT
GPIT MICRO
GPIA-ASSOC

Figure 5.2 CreateBitmap Function.


134 OS/2 PRESENTATION MANAGER GPI

i.f (hps!=GPI_ERROR) create bl.tmap


hbm = Gpi.CreateBl.tmap( -PS handle
-bl.tmap 1.nfo header
-opti.ons (do not 1.ni.ti.all.ze)
-no i.ni.ti.all.zati.on data
-no i.ni.ti.all.zati.on i.nfo table
in

I.f (hbm!=GPI_ERROR) /* select bl.tmap l.nto PS/DC


hbmr = Gpi.SetBitmap( hps /* -PS handle
hbm /* -bi.tmap handle
in

I.f (hbmr!=HBM_ERROR) /* erase the Bl.tmap


fRet = Gpi.Erase(hps); /* -PS handle

ptlposn.x = 20L; /* draw to bl.tmap


ptlposn.y = 20L:
1'f (fRet)
fRet = (B00L)Gpi.Charstri.ngAt( hps
&ptlposn
NBMAPCHARS
BMAPCHARS
in

I.f (hbmr!=HBM_ERROR) /* deselect bi.tmap from PS */


fRet = Gpi.SetBi.tmap( h /* -PS handle */
.N /* -bi.tmap handle (NULL) */
) != HBM_ERROR && fRet:

1.f (hps!=GPI_ERROR) /* destroy PS */


fRet = Gpi.Destroyps(hps) && fRet: /* -PS handle */

1.f (hdcMem!=DEV_ERROR) /* close the DC */


fRet = DevcloseDC( hdcMem /* -DC handle */
) != DEV_ERROR && fRet;

/* i.f any error occurred attempt to delete bl.tmap and set return code to */
/* GPI_ERROR. */

I'f (!fRet)
(
I.f (hbm!=GPI_ERROR)
G p i. D e 1 e t e 8 1. t in a p ( h b in ) ;
hbm = GPI_ERROR;
)

return ( hbm) ;

Figure 5.2 (co7?££7?L¢ecz)


BITMAPS 135

/* bl'tblt.C */
B00L Bi.tBlt( HAB hab
hps hps
HBITMAP hbm
LONG ICount
PP0INTL aptlpoi.nts
' LONG IROp
ULONG fl0pti.ons

/* Perform a Gpi.Bi.tBlt operati.on usl.ng the specl.fi.ed bi.tmap and parameters,


/* creati.ng and destroyi.ng the necessary PS and OD_MEMORY DC. It i.s assumed
/* that the bi.tmap 1.s not 1.ni.ti.ally selected 1.nto an OD_MEMORY DC. An error
/* 1.s returned i.f the speci.fi.ed hps I.s not associ.ated wi.th a DC.
/*
/* i.nputs: hab anchor block handle
/* hps PS handle
/* hbm bi.tmap handle
/* lcount count of target/source coordl.nate pol.nts
/* aptlpoi.nts array of target/source coordi.nate pol.nts
/* lRop rop mi.x code
/* fl0pti.ons opti.ons
/*

HDC hdc /* DC handle


HDC hdcMem = DEV ERROR /* OD_MEMORY DC handle
HPS hpsMem = GPI_ERROR /* PS handle for OD_MEMORY DC
HBITMAP hbmr = HBM ERROR /* Gpl.SetBi.tmap return code
B00L fRet = FALSE /* B00L return code
SIZEL si.zlps /* PS page si.ze

/* query device DC handle


hdc = Gpi.QueryDevi.ce(hps); /* -PS handle

I.f ((hdc!=NULL) && (hdc!=HDC_ERROR)) /* create OD_MEMORY DC for devi.ce


hdcMem = DevopenDC ( hab /* -anchor block handle
OD_MEMORY /* -DC type
1, * ,,
/* -token
OL /* -count of DEVOPENSTRUC i.terns
NULL /* -DEVOPENSTRUC data
hdc /* -DC handle i.dentifyi.ng devl.ce
in

s I. z 1 P S . cx=0 : /* set PS dl.mensl.ons = zero (default) */


S 1. Z 1 P S . cy=0 ;
1.f (hdcMem!=DEV_ERROR) /* create PS and associ.ate
hpsMem = Gpi.Createps( hab /* -anchor block handle
hdcMem /* -DC handle for associ.ati.on
& s 1' z 1 P S /* -PS sl'ze
PU_PELS /* -Optl.ons
G P I F_D E FAU LT
GPIT MICRO
G P I A_A S S 0 C

1.f (hpsMem!=GPI_ERROR) /* select bi.tmap 1.nto PS/DC


hbmr = Gpl.SetBitmap( hpsMem /* -PS handle
hbm /* -bi.tmap handle
in

Figure 5.3 BitBlt Function.


136 OS/2 PRESENTATION MANAGER GPI

I.f (hbmr!=HBM_ERROR) perform the Gpi.Bi.tBlt operati.on


fRet = (B00L)Gpi.Bi.tBlt( -target PS handle
-source PS handle
-count of poi.nts
-array of source and target pol.nts
-Rop mix value
- 0 p t ,' 0 n s
in
i.f (hbmr!=HBM_ERROR) /* deselect bi.tmap
fRet = Gpl.SetBi.tmap( hpsMem /* -PS handle
NULL /* -bl.tmap handle (NULL)
) != HBM_ERROR && fRet;

l.f (hpsMem!=GPI_ERROR) /* destroy PS


fRet = Gpi.Destroyps(hpsMem) && fRet; /* -PS handle

I.f (hdcMem!=DEV_ERROR) /* destroy DC


fRet = DevcloseDC( hdcMem /* -DC handle
) != DEV_ERROR && fRet;

return ( fRet ) :

Figure 5.3 (co7}££nttecz)

wcbltprt.c */
L WCBltToprl.nter(HAB hab. HPS hps, HBITMAP hbm)

Usl.ng a bi.tmap owned by the dl.splay, Bl.tBlt to a di.fferent devi.ce such


a prl.nter (i.dentl.fl.ed by the DC associ.ated wl.th hps) usl.ng Gpi.WCBi.tBlt
Note that a PS and OD_MEMORY DC are requl.red for the bi.tmap l.n order to
transfer ownershl.p to the new devl.ce, even though these are not actually
requi.red by Gpi.WCBi.tBlt. It i.s assumed that the bi.tmap l.s not i.ni.ti.ally
selected into any PS/DC and that any .start doc' and 'end doc' escapes
that are requi.red by the pri.nter are l.ssued before and after thi.s
functi.on by the caller.

Note that i.f the page uni.ts are PU_PELS, the source and target rectangl
wi.ll be i.denti.Gal and no stretchi.ng or compressi.on wi.11 occur. As the
source rectangle i.s l.n devl.ce coordl.nates (whl.ch are i.nclusl.ve-exclusl.ve
then (for Gpi.WCBi.tBlt) i.ts di.mensi.ons must be one larger than those
of the correspondi.ng target rectangle (whi.ch 1.s I.n world coordl.nates).

inputs: hab anchor block handle


hps PS handle
hbm bl.tmap handle

#defl.ne XTARGORG SOL


#defi.ne YTARGORG 50L

HDC hdc /* devi.ce DC handle


HDC hdcMem = DEV_ERROR /* OD_MEMORY DC handle
HPS hpsMem = GPI_ERROR /* PS handle
HBITMAP hbmr = HBM ERROR /* Gpl.SetBl.tmap return code
B00L fRet = FALSE /* B00L return code
BITMAPINFOHEADER bmplnfo /* bi.tmap i.nfo header
SIZEL si.zlps /* PS page si.ze
P0INTL aptlpoi.nts[4] /* target/source coordl.nate array

Figure 5.4 WCBltTOF+inter Function.


BITMAPS 137

hdc = Gpl.QueryDevl.ce(hps); /* query devi.ce DC handle


*/

i.f ((hdc!=NULL) && (hdc!=HDC_ERROR)) /* create OD_MEMORY DC for devi.ce


hdcMem = DevopenDC( hab /* -anchor block handle
OD_MEMORY /* -DC type
* ,, /* -token
OL /* -DEVOPENDATA count = 0
NULL /* -DEVOPENDATA (not requi.red)
hdc /* -DC handle i.dentl.fyi.ng devl.ce
in

S 1. ZI PS . CX=0 : /* set PS di.mensl.ons = zero (default) */


s i zl PS . cy-0 ;
l.f (hdcMem!=DEV_ERROR) /* create PS and associ.ate
hpsMem = Gpicreateps( hab /* -anchor block handle
. hdcMem /* -DC handle for associ.ati.on
& s 1' z 1 P S /* -PS sl'Ze
PU PELS /* -Optl.Ons
G P I F_D E FAU LT
G P I T_M I C R0
GPIA ASSOC
in
select bi.tmap I.nto thi.s PS/DC to */
i.f (hpsMem!=GPI_ERROR) transfer ownershi.p to new devi.ce */
hbmr = Gpl.SetBitmap( hpsMem PS handle */
hbm bl.tmap handle */
);

1.f (hbmr!=HBM_ERROR) /* deselect bi.tmap */


hbmr = Gpi.SetBi.tmap( hpsMem /* -PS handle */
NULL /* -bi.tmap handle (NULL)
*/
n
bmplnfo.cbFi.x = si.zeof(BITMAPINFOHEADER)
l.f (hbmr!=HBM_ERROR) /* query bi.tmap parameters
fRet = Gpl.QueryB1.tmapparameters( hbm /* bl.tmap handle
&bmplnfcj /* BITMAPINFOHEADER structure
in

aptl poi nts [0] . x XTARGORG /* target rectangle left


a p t 1 P 0 ,. n t s [ 0 ] . y YTARGORG /* target rectangle bottom
a p t 1 P o i. n t s [ 1 ] . x XTARGO RG+bmp I nf o . cx -1 /* target rectangle ri.ght
a p t 1 P 0 ,' n t s [ 1 ] . y YTARGORG+bmp I nf o . cy -1 /* target rectangle top
aptl poi nts [2] . x 0L /* source rectangle left
a p t 1 P 0 1' n t s [ 2 ] . y 0L /* source rectangle bottom
a p t 1 P o i. n t s [ 3 ] . x bmp I nfo . cx /* source rectangle left
a p t 1 P o 1. n t s [ 3 ] . y bmp I nfo . cy /* source rectangle rl.ght

l'f (fRet) perform the Bi.tBlt operati.on


fRet = (B00L)Gpl.WCB1.tBlt(
-target PS handle
-source bi.tmap handle
-count of pol.nts
-array of source & target pol.nts
-Rop mi.x value
- 0 p t 1' 0 n s

Figure 5.4 (co7i£Z7?z4ecz)


138 OS/2 PRESENTATION MANAGER GPI

1.f (hpsMem!=GPI_ERROR)
fRet = Gpl.Destroyps(hpsMem) && fRet: /* destroy the PS

I.f (hdcMem!=DEV_ERROR)
fRet = DevcloseDC(hdcMem)!=DEV_ERROR && fRet: /* close the DC

return (fRet);

Figure 5.4 (continued)

wbltload.c */
L WCBltLoadedBi.tmap(HPS hps, USHORT usResourceld)

Load a bi.tmap from the appli.cati.on EXE fl.le usi.ng Gpi.LoadBi.tmap and Bi.tBi.t
i.t to the PS usi.ng Gpi.WCBi.tBlt.

Note that i.f the page uni.ts are PU_PELS, the source and target rectangles
wi.1l be I.denti.cal and no stretchi.ng or compressi.on wl.ll occur. As the
source rectangle i.s i.n devl.ce coordi.nates (whl.ch are i.nclusi.ve-exclusi.ve)
then (for Gpi.WCBl.tBlt) l.ts dl.mensl.ons must be one larger than those
of the correspondi.ng target rectangle (whl.ch is i.n world coordi.nates).

i.nputs: hps PS handle


usResourceld Bi.tmap resource Id

#defl.ne XWTARGORG SOL


#defi.ne YWTARGORG 50L

HBITMAP hbm /* bi.tmap handle


B00L fRet = FALSE /* B00L return code
P0INTL aptlpoi.nts[4] /* target/source coordl.nate pol.nt array
BITMAPINFOHEADER bmplnfo /* bi.tmap 1.nfo header

/* load bl.tmap from appll.cati.on exe fi.1e


hbm = Gpl.LoadBi.tmap( hps /* -PS handle 1.denti.fyl.ng devi.ce
(HMODULE)NULL /* -Resource ID NULL I..e. appl. EXE fi.1e
usResourceld /* -ID i.n resource fi.1e
OL /* -bi.tmap wi.dth 0 -use orl.gl.nal value
OL /* -bi.tmap hei.ght 0 -use ori.gi.nal value
in

bmplnfo.cbF1.x = sl.zeof(BITMAPINFOHEADER)
I.f (hbm!=GPI_ERROR) ery bi.tmap parameters
fRet = GpiQueryBi.tmapparameters tmap handle
TMAPINFOHEADER structure

Figure 5.5 WCBltLoadedBitmap Function.


BITMAPS

a p t 1 P 0 1' n t s [ 0 ] . x XWTARGORG /* target rectangle left


a p t 1 P 0 1' n t S [ 0 ] . y YWTARGORG /* target rectangle bottom
a p t 1 P o i. n t s [ 1 ] . x XWTARGO RG+bmp I nfo . cx -1 /* target rectangle rl.ght
aptl poi nts[1] .y YWTARGO RG+bmp I nf o . cy -1 /* target rectangle top
a p t 1 P o 1. n t s [ 2 ] . x 0L /* source rectangle left
a p t 1 P o i. n t s [ 2 ] . y 0L /* source rectangle bottom
a p t 1 P o I. n t s [ 3 ] . x bmp I nfo . cx /* source rectangle left
a p t 1 P 0 ,' n t s [ 3 ] . y bmp I n f o . cy /* source rectangle rl.ght

i.f (fRet) /* perform the Bi.tBlt operati.on


fRet = Gpl.WCBi.tBlt( hps /* -target PS handle
hbm /* -source bi.tmap handle
4L /* -count of poi.nts
aptlpoints /* -array of source and target poi.nts
ROP_SRCCOPY /* -Rop mi.x value
BBO_OR /* -opti.ons
) !-GPI_ERROR;

1.f (hbm!=GPI_ERROR) /* delete bl.tmap


fRet = Gpi.DeleteBi.tmap(hbm) && fRet; /* -bi.tmap handle

return (fRet);

Figure 5.5 (continued)

/* reali.ze.c */
B00L Reall.zecolorlmage( HAB hab
HPS hps
PBYTE pblni.tData
PBITMAPINF0 pbmi.InfoTable

/* Di.splay an 8 bi.t per pel scanned i.mage usi.ng the color reali.ze functi.ons
/* 1.f supported. Note that Gpi.Unreali.zecolorTable must be 1.ssued subsequently
/* to unreali.ze the color table.
/*
/* i.nputs: hab anchor block handle
/* hps Ps handle
/* pblni.tData Bl.tmap l.mage data
/* pbmi.InfoTable Bi.tmap BITMAPINF0 table
/*
/* If the I.nput data i.s provi.ded by a .bmp bl.tmap resource fi.le, the l.nput
/* parameters can be establl.shed from the data as shown below.
/*
/* PBYTE pbB1.tmapF1.leData ; pol.nter to start of .bmp fi.1e data
/* PBITMAPFILEHEADER pbmfh ; pol.nter to BITMAPFILEHEADER
/*
/* 1.f (((PBITMAPARRAYFILEHEADER)pbB1.tmapFi.1eData)->usType == BFT_BITMAPARRAY)
/* pbmfh = (PBITMAPFILEHEADER)((PBYTE)pbBi.tmapFi.leData
/* + sl.zeof(BITMAPARRAYFILEHEADER) -sl.zeof(BITMAPFILEHEADER));
/* else
/* pbmfh = (PBITMAPFILEHEADER)pbB1.tmapFi.1eData:
/* i.f (pbmfh->usType!=BFT_BMAP)
/* return(FALSE):
/* pbmi.InfoTable = (PBITMAPINFO)((PBYTE)pbmfh+sl.zeof(BITMAPFILEHEADER)
/* -si.zeof(BITMAPINFOHEADER));
/* pblni.tData = (PBYTE)pbBi.tmapF1.1eData+pbmfh->offB1.ts;
/*

Figure 5.6 Realizecolorlmage Function.


140 OS/2 PRESENTATION MANAGER GPI

HBITMAP hbm = GPI ERROR /* bi.tmap handle


HBITMAP hbmr = HBM-ERROR /* HBITMAP return code
B00L fRet = FALSE /* B00L return code
HPS hpsMem = GPI_ERROR /* PS handle
HDC hdcMem = DEV_ERROR /* DC handle
P0INTL aptlpoi.nts[3] /* target/source coordi.nate poi.nt array
LONG INumcolors /* number of bl.tmap color table colors
PBYTE pbcolorTable = NULL /* color table poi.nter
PBYTE pbcolors /* color table poi.nter
PBYTE pbcolorlnfo /* color 1.nfo
SIZEL si.zlps /* PS page si.ze
HDC hdc = HDC ERROR /* DC handle
INTI /* array i.ndex
ULONG ulReall.ze /* reali.ze optl.on
LONG IDevcolorsupport /* color table support devi.ce cap
LONG INumDevi.cecolors /* number of colors devl.ce cap

/* allocate color table memory


lNumcolors = (LONG)pow(2.0, (double)pbmi.InfoTable->cBl.tcount);
pbcolors = pbcolorTable = malloc((SHORT)lNumcolors*si.zeof(LONG));

I.f (pbcolorTable!=NULL) /* query DC handle for target devi.ce */


hdc = Gpl.QueryDevi.ce(hps): /* -PS handle */

1.f( hdc!=HDC_ERROR) /* open OD_MEMORY DC


hdcMem = DevopenDC( hab /* -anchor block handle
OD_MEMORY /* -DC type
* ,, /* -token
OL /* -DEVOPENSTRUC count (0)
NULL /* -DEVOPENSTRUC (n/a)
hdc /* -compati.ble hdc
in

sl'zlps.cx -0:
sl'ZIPS.cy -0:
I.f (hdcMem != DEV_ERROR) /* create PS and assocl.ate
hpsMem = Gpl.Createps( hab /* -anchor block handle
. hdcMem /* -DC handle for associ.ate
& s 1` z 1 P S /* -page sl'ze
PU PELS /* -Optl'Ons
GPTT MICRO
GPIA-ASSOC

/* construct the color table for Gpi.CreateLogcolorTable from the BITMAPINFO


/* rgb color array

I. f ( hpsMem ! =GP I_ERRO R )


(

pbcolorlnfo = (PBYTE)pbml.InfoTable + pbmi.InfoTable->cbFl.x;


for (I.=0; 1.<(INT)lNumcolors: i.++ )
(
*pbcolors = *pbcolorlnfo;
*(pbcolors+1) = *(pbcolorlnfo+1):
*(pbcolors+2) = *(pbcolorlnfo+2);
*(pbcolors+3) = 0:
pbcolors += 4;
pbcolorlnfo += 3;
)

Figure 5.6 (cot?£Znztecz)


BITMAPS 141

/* query number of colors supported


fRet = Devouerycaps( hdc /* -DC handle
CAPS_COLORS /* -start
.1L /* -count
&lNumDevl.cecolors /* -returned number of colors

)
l'f (fRet) /* query reall.ze support
fRet = DevQuerycaps( hdc /* -DC handle
CAPS_COLOR_TABLE_SUPPORT /* -start
1L /* -count
&1Devcolorsupport /* -returned flags
in
1.f (1Devcolorsupport & CAPS_COLTABL_REALIZE)
ulReali.ze= LCOL_REALIZABLE;
else
ulReali.ze = OL;
/* create logical color table for
/* bi.tmap PS (must be reali.zable
1'f (fRet) /* but need not be reali.zed)
fRet = Gpi.CreateLogcolorTable( hpsMem /* -PS handle
LCOL_RESET /* -vall.d options
u 1 R e a 1 i. z e
LCOLF_CONSECRGB /* -format
OL -start 1.ndex /*
ml.n( 1Numcolors /* -number of colors
lNumDevi.cecolors)
(PLONG)pbcolorTable /* -RGB table data

1' f ( f R e t ) /* create and 1.nl.tl.all.ze bi.tmap


hbm = Gpl.CreateBl.tmap( hpsMem /* -PS handle
(PBITMAPINFOHEADER)pbmi.InfoTable /* -i.nfo header
CBM_INIT /* -opti.ons
pblnl.tData /* -l.ni.tl.all.zati.on 1.nfo table
pbmi.InfoTable /* -i.ni.ti.all.zati.on data
in

I.f (hbm!=GPI_ERROR) /* select bl.tmap l.nto PS/DC


hbmr = Gpl.SetBi.tmap( hpsMem /* -PS handle
hbm /* -bi.tmap handle
n
/* create reali.zable color table for
I.f (hbmr!=HBM_ERROR) /* target PS
fRet = Gpl.CreateLogcolorTable( hps /* -PS handle
LCOL_RESET /* -opti.ons
u 1 R e a 1 i. z e
LCOLF_CONSECRGB /* -format
OL /* start 1.ndex
ml.n( lNumcolors /* number of colors
lNumDevicecolors)
(PLONG)pbcolorTable/* RGB color table data*/
) && fRet:

i.f (fRet && (1Devcolorsupport & CAPS_COLTABL_REALIZE)) /* reall.ze color */

fRet = Gpl.Reali.zeco|orTabie(hps); (:?;§T;a::I:eall.Ze supported =(

Figure 5.6 (con£Z7}L4ecz)


142 OS/2 PRESENTATION MANAGER GPI

aptl poi nts [0] . x OL: /* target rectangle left


aptl poi nts[0] .y OL; /* target rectangle bottom
aptl poi nts [ 1 ] . x pbmi I nfoTabl e ->cx /* target rectangle rl.ght
a p t 1 P 0 1' n t s [ 1 ] . y p b in i. I n f o T a b 1 e - > c y /* target rectangle top
a p t 1 P o 1. n t s [ 2 ] . x OL: /* source rectangle left
a p t 1 P o 1. n t s [ 2 ] . y OL; /* source rectangle bottom

1'f (fRet) perform the Bi.tBlt operati.on


fRet = (B00L)Gpi.Bi.tBlt( -target PS handle
-source bi.tmap handle
-count of poi.nts
-array of source and target
-Rop mi.x value
- 0 p t 1' 0 n s
in

1.f (hbmr!=HBM_ERROR) /* deselect the bi.tmap


fRet = Gpi.SetBl.tmap( hpsMem /* -PS handle
NU /* -bi.tmap handle (NULL)
) != HBM_ERROR && f

l.f (hbm!=HBM_ERROR) /* delete bl.tmap


fRet = Gpi.DeleteBi.tmap(hbm) && fRet; /* -bi.tmap handle

I.f (hpsMem!=GPI_ERROR) /* destroy the PS


fRet = Gpl.Destroyps(hpsMem) && fRet: /* -PS handle

i.f (hdcMem!=DEV_ERROR) /* destroy the DC


fRet = DevcloseDC( hdcMem /* -DC handle
) != DEV_ERROR && fRet:

f ree ( pbcol orTabl e ) ; /* f ree memory */

return ( f Ret ) ;

Figure 5.6 (continued)


Color Tables

An application may specify a color attribute for drawing (e.g., using


Gpisetcolor) as either an RGB or index value, according to the color table mode
(index or RGB). A logical color table in index mode is a map of color index to
RGB value. In RGB mode, RGB values are specified directly without any
mapping.
An RGB color value is either a three or four byte integer containing eight bit red
(R), green (G), and blue a3) intensity values (i.e., R*65536+G*256+B). Note that
in memory, the order of the bytes is reversed and they will appear as BGR values.
The presentation drivers provide psychometric rather than linear RGB support.
This means that increased RGB value gives a visually linear increase in intensity
rather one based on photon intensity.
An example of the index mode color table model is illustrated in Figure 6-1. Note
that there is a father mapping between the logical color table RGB values and
those in the physical device palette to obtain the device RGB color that most closely
matches the required color. If the same color needs to be reused (i.e., set) a number
of times then index mode offers a clear performance advantage over RGB mode.
In RGB mode the RGB to nearest physical color mapping is repeated each time the
color is set whereas in index mode it is performed only once.

THE STANDARD COLOR TABLE

The default (or reset) color table mode is index mode and the system provides a
default color table of 16 entries with symbolic constants defined for each, plus
certain other predefined non-index values as illustrated below.

143
144 OS/2 PRESENTATION MANAGER GPI

PS LOGICAL
COLOR TABIE
(INDEX HOPE)

INDEX RGB PHYSICAL


VALUE I NDE X
PHYSICAI'
RGB-0 5 DEVICE
PAIJEm
RGB-1 10
I NDEX RGB
4
:.' ,-:.I',:1',. :.',:.- .:,.I,.: .,: . :,;.:
RGB-2 VALUE

ROB-3 15

RGB+ 0

RGB-5 3

RGE-6 9

RGB-7 8

RGB-8 1

Rob-9 13

RGB-10 6

RGB-11 14

RGB-12 2

RGB-13 12

RGB-14 7

RGB-15 11

Note: RGB-6a, for example, 1s the dovlc® RGB color that Dost closely
DatcheB ROB-6, the r®qu®sted RGB color.

Figure 6.1 Logical and Physical Color Table Model.

Ilredefined non-index values :


Value -5 CLR FALSE All color planes o
-4 CLR TRUE AIl color planes 1

-3 CLR DEFAUIIT Default color

-2 CLR W'IIITE White

-1 CLR BLACK Black

Hredefined (standard) color table index values:


COLOR TABLEs ias

0 CLR BACKGROUND Device background


color
(SYSCLR WINDOW
for displa;)
1 CLR BLUE Blue
2 CLR RED Red
3 CLR PINE Pink
4 CLR GREEN Green
5 CLR CYAN Cyan
6 CLR YELLOW Yellow
7 CLR NEUTRAL Device foreground color
(SYSCLR WINDOW-
TEXT for-display)
8 CLR DARKGRAY Dark Gray
9 CLR DARKBLUE Dark Blue
10 CLR DARKRED Dark Red
11 CLR DARKPINK Dark Pink
12 CLR DARKGREEN Dark Green
13 CLR DARKCYAN Dark Cyan
14 CLR BROWN Broun
15 CLR PALEGRAY Pale Gray
RGB values in both index and RGB mode are napped to the nearest available color
in the predefined device palette. A device may provide additional colors for use in
area fill by dithering, which is a process whereby unavailable colors are simulated
by using different colors for alternate pels.
Clearly, for devices that support fewer than 16 colors, it is possible for more than
one index in the standard color table color to map to the same actual RGB device
color.

LOGICAL COLOR TABLE CREATION

Using GpicreateLogcolorTable, an application can provide its own set of indexed


RGB mappings to define its own logical color table. This is illustrated by the
function CreateLogicalcolorTable in Figure 6-2. The maximum index value sup-
ported for a particular device can be determined using DevQuerycaps
(CAPS_COLOR_INDEX) and should normally be at least 63, even for a mono-
chrome device.
146 OS/2 PRESENTATION MANAGER GPI

GpicreatellogcolorTable includes both a format and an options parameter. The


format parameter specifies one of the following:

LCOLF RGB

This sets the color table to RGB mode.

LCOLF INDRGB

This loads the supplied color data, which consists of an array of index-RGB pairs.
Depending on its index value, each new pair of index-RGB values will either
replace an existing entry or extend the table. If the color table was previously in
RGB mode, it is switched to index mode and reset to the default color table before
the new data is loaded.

LCOLF CONSECF}GB

This loads the supplied color data, which consists of an array of RGB values with
consecutive indices starting from a specified index. Depending on its index value,
each new RGB value will either replace an existing entry or extend the table. If
the color table was previously in RGB mode, it is switched to index mode and reset
to the default color table before the new data is loaded.

The options parameter allows any combination of the following options to be


specified:

LCOL RESET

This resets the color table to the default color table before loading the new data.
This reset is implicit whenever the format parameter specifies a switch from RGB
to index mode.

LCOLF REALIZABLE

If supported by the presentation driver, this creates a realizable color table (see
below). This option is valid only for index mode (i.e., LCOLF_INDRGB or
LCOLF_CONSEGRGB) and will force the LCOL_PURECOLOR option for any
drivers that support realizable color tables.
COLOR TABLES 14]

LCOLF PURECOLOR

This indicates that only pure colors are required. Dithering may not be used to
simulate unavailable colors.

REALIZABLE COLOR TABLES

For non-realizable color tables in either index or RGB mode, each RGB value is
napped to the nearest available RGB value in the fixed physical color palette of
the device. Realizable color table support enables an application to create its own
realizable color table and then realize it (i.e., reload the device color palette with
application specified RGB values). This enables high quality scanned images to be
displayed using bitmaps.
The actual colors obtained when a realizable color table is realized depend, of
course, on the color resolution of the particular device. The RGB values are
assumed to be psychometric and are corrected accordingly by the driver before
they are loaded into the physical device palette. It is not possible to load the device
palette with unmodified RGB values from an application.
Forabitmap,noremappingofbitmapconteritdataoccurswhenthecorrespond-
ing PS color table (i.e., the color table of the PS associated with the OD MEMORY
DC into which the bitmap is selected) is realized. For performance r:asons, the
color mapping for a bitmap occurs when its contents are initialized. A suitable
realizable color table must therefore be created Out not realized) before the
bitmap data is initialized.
Realizable color tables are supported only in index mode. To be realized, a color
table must first be created with the LCOLF_REALIZABLE Option. A realizable
color table can then be realized and unrealized using:
GpiRealizecolorTable; and
GpiunrealizecolorTable.
A complete screen repaint is essential after each of these operations in order to
obtain the correct display screen appearance.
Clearly, reloading the device color palette will affect the appearance of all
windows on the display screen. To avoid interfering with other applications visible
on the display screen, GpiRealizecolorTable should only be issued when the
relevant window is maximized and has the input focus. GpiuhRealizecolorTable
should be issued as soon as the window is unmaximized or loses the input focus.
For hard copy devices such as printers, realize is not applicable. These do not
have the problem of displaying the output from different applications simulta-
neously and should therefore always provide the best color match possible for the
requested colors.
While a realizable color table is unrealized, its colors will be displayed from the
physical device palette exactly as if it were realized, and are therefore unlikely to
appear correct.
On early levels of IBM OSA Version 1.2, GpiRealizecolorTable was not sup-
lan Os/2 pRESENTATioN MANAc;ER Gpl

ported by any driver. Support was added, together with gray scale palette im-
provements for image support, on a 1.2 Corrective Service Diskette and also on
Version 1.3. Support is for the 8514/A display driver only and it is not currently
supported by any other driver.
Realizable color tables should not be dissociated from their DC or the
LCOLF_REALIZABLE (and LCOLF_PURECOLOR) option will be lost. See chap-
ter 5 for a description of how bitmaps are used with realizable color tables.

COLOR 0lJERIES

A number of color query functions exist as follows:

GpiQueryLogcolorTable

For Index Mode, this returns the contents of the logical color table.
For RGB Mode, it provides a return value indicating that the table is in RGB mode.

GpiQuerycolorData

This returns the format (default, Index Mode, RGB Mode) and largest index
currently loaded for the logical color table.

GpiQueryRealcolors

This returns the RGB values of the actual colors available on the associated output
device. If applicable, it can be used to obtain the values that would apply when a
realizable color table is realized.

GpiQueryNearestcolor

This returns the actual RGB color of the associated device that is closest to a
specified RGB value.

GpiQuerycolorlndex

This returns the logical color index for the associated device color that is closest to
a specified RGB value.

GpiQueryRGBColor

This returns the actual RGB value that will be provided by the associated device
for a specified logical color index. If applicable, it can be used to obtain the value
that would apply when a realizable color table is realized.
COLOR TABLES 149

createlo.c */
OL CreateLogi.calcolorTable( HPS hps )

Reset the logl.Gal color table and load l.t 1.n l.ndex mode wl.th l.ndexed-RGB
val ues .

I.nputs: hps PS handle

#defi.ne NALTABLEI 32L

B00L fRet : /* B00L return code

stati.c LONG alTable[NALTABLEI] =


( OL, OxOOOOOOOOL /* (0) black (RGB_BLACK)
1L, OxOOOOOO80L /* (1) dark blue
2L, OxOOOO8000L /* (2) dark green
3L, OxOOOO8080L /* (3) dark cyan
4L. OxOO800000L /* (4) dark red
5L, OxOO800080L /* (5) dark pi.nk
6L, OxOO808000L /* (6) brown
7L, OxOO808080L /* (7) pale gray
8L, Ox00202020L /* (8) dark gray
9L, OxOOOOOOFFL /* (9) blue (RGB_BLUE)
10L, OxOOOOFF00L /* (A) green (ROB_GREEN)
llL, OxOOOOFFFFL /* (8) cyan (RGB_CYAN)
12L, OxOOFF0000L /* (C) red (RGB_RED)
13L, OxOOFF00FFL /* (D) pink (RGB_PINK)
14L, OxOOFFFF00L /* (E) yellow (RGB_YELLOW)
15L, OxOOFFFFFFL /* (F) whl.te (RGB_WHITE)
in

fRet = Gpl.CreateLogcolorTable( hps PS handle */


LCOL_RESET 0 p t 1' 0 n */
LCOLF_INDRGB format */
OL start l.ndex */
NALTABLEI number of alTable elements*/
alTable ROB color table array */
in

return ( fRet ) :

Figure 6.2 CreateLogicalcolorTable Function.


Coordinate Spaces and Transformation

The Gpi transform functions provide a mechanism for two dimensional scaling,
translation, rotation, and shear in graphics pictures (and text). Device indepen-
dence is provided by allowing an application to define its picture in device
independent page units.
Chapter 1 illustrated how to perfo]rm simple rotation, scaling, and shear using
the transformation `helper' functions: GpiRotate, Gpiscale, and GpiThanslate, and
also pointed out that such operations could also be accomplished by specifying the
required matrices directly without using the `helper' functions. This is illustrated
in the examples below (see Appendix 3 for a brief introduction to coordinate
transformations and matrices).
For rotation, the following two sequences are exactly equivalent, performing a
30-degree counterclockwise rotation about the point (100,150).

/* rotate by 30 degrees counterclockwi.se about the poi.nt (100,150) */

ptlposn.x = 100L; /* x center of rotati.on */


ptlposn.y = 150L; /* y center of rotati.on */
Gpl.Rotate( hps, &matlfModel, TRANSFORM_REPLACE, MAKEFIXED(30,0), &ptlposn ):
Gpi.SetModelTransformMatri.x( hps, 9L, &matlfModel , TRANSFORM_ADD):

and
(
stati.c MATRIXLF matlfModel = { Oxl0000, OL, OL, OL, Oxl0000, OL, OL, OL,1L }:

/* translate the poi.nt (100,150) to the orl.gi.n

matlfModel.IM31 = -100L; /* x translati.on (-100)


matlfModel.IM32 = -150L; /* y translatl.on (-150)
Gpl.SetModelTransformMatri.x( hps, 9L, &matlfModel , TRANSFORM_ADD);
matlfModel .1M31 = matlfModel .IM32 = OL:

150
COORDINATE SPACES AND TRANSFORMATION 151

/* rotate by 30 degrees counterclockwl.se */

matlfModel .fxMll = OxOOOODD63: /* Cos(30)*Oxl0000 rotati.on */


matlfModel .fxM12 = OxOOOO8000L: /* Si.n(30)*Oxl0000 rotati.on */
matlfModel .fxM21 = OxFFFF8000; /* -Si.n(30)*Oxl0000 rotati.on */
matlfModel .fxM22 = OxOOOODD63: /* Cos(30)*Oxl0000 rotatl.on */
Gpi.SetModelTransformMatrl.x( hps, 9L, &matlfModel , TRANSFORM_ADD);
matlfModel .fxMll = matlfModel .fxM22 = Oxl0000;
matlfModel .fxM12 = matlfModel .fxM21 = OL:

/* translate by (100,150) back to the orl.gl.nal posl.ti.on

matlfModel.IM31 = +100L; /* x translati.on (+100)


matlfModel.1M32 = +150L; /* y translati.on (+150)
Gpi.SetModelTransformMatrl.x( hps, 9L, &matlfModel , TRANSFORM_ADD);
matlfModel .IM31 = matlfModel .1M32 = OL:
)

For scaling, the following two sequences are exactly equivalent, performing scal-
ing by a factor of 2.0 in both the x and y direction about the point (100,150).

(
/* scale by 2.0 1.n both x and y dl.rectl.on about the poi.nt (100,150) */

afxscale[0] = MAKEFIXED(2,0); /* x scali.ng = 2.0 */


afxscale[1] = MAKEFIXED(2,0); /* y scall.ng = 2.0 */
ptlposn.x = 100L: /* x center of scali.ng */
ptlposn.y = 150L; /* y center of scali.ng */
Gpi.Scale( hps, &matlfModel, TRANSFORM_REPLACE, afxscale, &ptlposn);
Gpi.SetModelTransformMatrl.x( hps, 9L, &matlfModel, TRANSFORM_ADD);

and
(
stati.c MATRIXLF matlfModel = { Oxl0000, OL, OL, OL, Oxl0000, OL, OL, OL,1L );

/* translate the pol.nt (100,150) to the orl.gl.n

matlfModel.IM31 = -100L: /* x translati.on (-100)


matlfModel.IM32 = -150L: /* y translati.on (-150)
Gpi.SetModelTransformMatri.x( hps, 9L, &matlfModel , TRANSFORM_ADD);
matlfModel .1M31 = matlfModel .1M32 = OL:

/* scale both x and y by a factor of 2.0

matlfModel.fxMll = Ox00020000: /* x scall.ng (ti.mes 2.0)


matlfModel.fxM22 = Ox00020000: /* y scall.ng (tl.mes 2.0)
Gpi.SetModelTransformMatri.x( hps, 9L, &matlfModel , TRANSFORM_ADD);
matlfModel .fxMll = matlfModel .fxM22 = Oxl0000:

/* translate by (100,150) back to the ori.gi.nal posi.ti.on

matlfModel.1M31 = +100L; /* x translati.on (+100)


matlfModel.1M32 = +150L; /* y translati.on (+150)
Gpl.SetModelTransformMatrl.x( hps, 9L, &matlfModel, TRANSFORM_ADD):
matlfModel .1M31 = matlfModel .IM32 = OL;
)

For translation, the following two sequences are exactly equivalent, performing
translations of +50 and +100 in the x and y directions respectively.
152 OS/2 PRESENTATION MANAGER GPI

(
/* translate by +50 and +100 i.n the x and y di.rectl.ons respecti.vely */

ptlposn.x = SOL;
ptlposn.y -100L:
Gpl.Translate( hps /* -PS handle */
&matlfModel /* -transform matrl.x */
TRANSFORM_REPLACE /* -Opt,.Ons */
&ptlposn /* -translati.on coordi.nates */
n
Gpi.SetModelTransformMatri.x( hps /* -PS handle */
9L /* -number of matri.x elements */
&matlfModel /* -transform matrl.x */
TRANSFORM_ADD /* -Opt,'Ons */
in
)

and
(
stati.c MATRIXLF matlfModel = { Oxl0000. OL. OL, OL, Oxl0000, OL, OL, OL,1L };

/* translate by +50 and +1001.n the x and y di.recti.ons respecti.vely


matlfModel.1M31 = +50L; /* x translati.on (+50)
matlfModel.1M32 = +100L; /* y translati.on (+100)
Gpl.SetModelTransformMatri.x( hps /* -PS handle
9L /* -number of matri.x elements
&matlfModel /* -transform matri.x
TRANSFORM_ADD /* -Optl'ons
in
matlfModel .1M31 = matlfModel .IM32 = OL;
)

Note from the above examples that (when transforming a figure about a given
point) for operations other than translation, the figure origin must first be trans-
lated to (0,0) before the required (rotate, scale, shear, etc.) matrix operation is
performed, and translated back to its required position afterward. This is import-
ant to avoid undesirable translations (which occur when the translation offset is
scaled or rotated together with the figure). This translation is explicit when using
the `set transform' functions directly, whereas with the `helper functions' GpiRot-
ate and Gpiscale it is implicit. Note also that the TRANSFORM_ADD option
allows the transformi to be incrementally accumulated in steps, rather than being
overwritten each time.
The above examples illustrate use of the model transform matrix, which is
intended for transforming individual elements and figures within the picture
during drawing. Chapter 1 also mentioned the default view matrix that is provided
for scaling and scrolling the whole picture. The GPI, in fact, provides a hierarchy
of coordinate spaces and transforms each with its own distinct purpose.
Application specified coordinates are called world coordinates. These are trans-
formed by the various presentation space transforms, to provide the device inde-
pendent version of the picture in the PS page from where it is rendered to the
device. The units of the PS page together with the device resolution determine the
device transformi required to ensure that an inch (say) in the PS page appears as
an inch on the device. These conversions from world to presentation page to device
coordinates via the presentation space and device transforms are illustrated in
Figure 7-1.
COORDINATE SPACES AND TRANSFORMATION 153

!F:::in.te ir
Present.tlon
M Space TranafW

PS P®8®

Figure 7.1 nresentation Space and Device Thansforms.


PAGE UIIITS

As mentioned above, the page units together with the device resolution determine
the device transform. Page units are typically fractions of an inch or meter, but
can also be specified as device coordinates (i.e., PU_PELS) if required. The page
units (of the PS page) are specified as parameters to Gpicreateps and Gpisetps
(see chapter 2). For a cached PS, the page units default to PU_PELS.
The system provides the following choice of page units:
PU_ARBITRARY page units cause the picture to be displayed as
large as possible in the available device output area while preserv-
ing its aspect ratio (such that a circle remains a circle). For a display
window, the available device output area is assumed to be the maxi-
mized window or screen size.
PU_PELS page units are device units. These are pels for a raster
device and for a plotter are equal to the minimum line increment.
PU_LOMETRIC page units are 0.1 mm.
PU_HIMETRIC page units are 0.01 mm.
PU_LOENGLISH page units are 0.01 inches.
PU_HIENGLISH page units are 0.001 inches.
PU TWIPS page units are I/1440 inches (i.e., 1/20 of a printers
point)i
Although not recommended, an application can modify the device transfo]rm. using
Gpisetpageviewport to define its own page units (see below).
In addition to specifying the page units, an application must specify the page
154 OS/2 PRESENTATION MANAGER GPI

dimensions. For PU_ARBITRARY page units, page dimensions are important in


determining the drawing limits and the aspect ratio of the visible picture on the
device. The application may specify any convenient values up to Ox07FFFFFF
(134217727) but very small values should be avoided.
For page units other than PU_ARBITRARY, the precise page dimensions are,
with certain exceptions, fairly unimportant. If the PS is to be used for printing,
then it is good practice to match the page dilnensions to the size of the output form
where this is possible, otherwise they can be defaulted, or set to some sensible
values that minimize the risk of internal overflow. Apart from with PU_ARBI-
TRARY page units, the page dimensions are important under the following
conditions:
• If Gpisetpageviewport is being issued by an application to define its
own page units, then the page dimensions are important in that,
together with the page viewport, they define the new device trams-
form and page units (see below).
• When printing via the spooler, if queue processor options other then
"XFM=0" (which is not the default) are specified then the page
dimensions should accurately reflect the size of the output form. This
will ensure that the `FIT=' and `ARE=' (scale to fit, etc.) parameters
provide the correct results.
• If the PS is used for recording a MetaFile, the page dimensions will
be recorded in the MetaFile as the picture dimensions and may be
used when the MetaFile is subsequently displayed.

PRESEHTATIOM SPACE TRANSFORMS

Apart from device transform, three presentation space transforms are visible to
an application. These are:
• Model Thansformi (including segment and instance transform).
• Viewing Thansform.
• Default Viewing Thransform.
Other system transforms, such as the translation associated with the position of
the window on the display screen, do exist, but these are transparent to an
application.
Model transform, viewing transfo]rm and default viewing transform are all
presentation space transforms affecting the appearance of the device independent
picture in the PS page, whereas device transfo]rm renders the PS page contents to
the device. The transformation `pipeline' showing the order in which these trans-
forms are applied is illustrated in Figure 7-2 and can be represented mathemati-
cally as:

D[d Yd 1] = B[w Yw 1].[M].M.[DVT].[D]


where:
COORDINATE SPACES AND TRANSFORMATION 155

Xd Yd = device coordinates;
Xw Yw = world coordinates;
M = model transforml matrix;
V = viewing transfo]rm. matrix;
DVT = default viewing transformi matrix; and
D = device transfo]rmi matrix.
In practice, world coordinates are not actually converted to each intermediate
coordinate space. The transforms are combined intemally allowing coordinates to
be transformed directly from world to device coordinates by the system in a single
operation. Nevertheless, the illustration in Figure 7-2 provides an accurate and
useful model for understanding the operation and purpose of the individual
matrices.

World
Coordinate
Space
HH
Model
Space
H
Vlowlng Transform

Default
Page
Coordin®to
Space

E3:::u=:Trap
PS page

Device
Coordinate
Space

Figure 7.2 Gpi 'Thansformation Pipeline.


156 OS/2 PRESENTATION MANAGER GPI

The model and viewing transforms are picture attributes that can be varied
during drawing for the purpose of picture constmction, whereas the default
viewing (and device) transform. are environlnent attributes that should be estab-
lished before the picture is drawn.
Many applications need not be concerned with, or use, all of the available
transforms. As stated above, the basic model transfo]rm should be used for
transforming individual elements within a picture and the default viewing
transform for scrolling and scaling (i.e., pan and zoom) the entire picture. In
addition to the GpisetModelThansformMatrix function, the instance and segment
transforms provide two additional ways of controlling the model transformi
drawing attribute. Instance transform is a model transform specified with
GpicallsegmentMatrix, for use with called retained segments, and segment
transform is a model transform used exclusively at the star of retained segments.
Viewing transform is provided to enable the contents of an entire graphics
segment to be transformed without interference from (model) transform opera-
tions inside the segment.
The GpisetModelThansform.Matrix and GpisetDefaultviewMatrix functions
both have an options parameter controlling the way in which the new and existing
matrix values are combined. This may specify one of the following:

TRANSFORM REPLACE

The new transform matrix elements provided with the call are used to replace the
existing values.

TRANSFORM ADD

The new and existing transform matrix elements are combined by concatenating
the new matrix after the existing matrix. This can be represented mathematically
by:

[matrix] = [existing matrix]. [new matrix]


or : P[out Yout 1] = P[in Yin 1].[existing matrix].[new matrix]
In a pipeline model (such as that used in Figure 7-2), the output of the original
matrix is effectively transformed futher by the new matrix (which is below it).
This option is more commonly used than TRANSFORM PREEMPII

TRANSFORM PREEMPT

The new and existing transformi matrix elements are combined by concatenating
the new matrix before the existing matrix. This can be represented mathemati-
cally by:

[matrix] = [new matrix]. [existing matrix]


or: [Xout Yout 1] = P[in Yin 1].[new matrix].[existing matrix]
COORDINATE SPACES AND TRANSFORMATION 15J

In a pipeline model (such as that illustrated in Figure 7-2), the new matrix is
placed before the original, and the output of the new matrix is effectively trans-
formed further by the original matr.ix (which is below it).

MATRIX PARAMETER FORMATS

As explained in Appendix 3, any two dimensional transformi operation can be


represented by the general equations:
Xout = Xin.Mll + Yin.M21 + M31
Yout = Xin.M12 + Yin.M22 + M32
which are be represented in matrix formi as:

M21 M22 0
M31
IMll M32 0
M12 1

These matrix elements are passed as a parameter to any of the `set transformi
matrix' functions in a MATRIXLF structure in the order:
[ Mll M12 0 M21 M22 0 M31 M32 1 ]
The corresponding fields of the MATRIXLF structure are:
[fkM11 fkM12 lM13 fkM21 fxM22 lM23 lM31 lM32 lM33 ]
The elements fkMll, fkM12, fkM21, and fkM22 are of type FIXED while the
remainder are of type LONG. FIXED numbers are four-byte values with a notional
binary point between bytes 3 and 4. (See chapter 1 for a description of FIXED
numbers.)

000RD"ATE LIMITS

As explained in chapter 1, in order to avoid coordinate overflow, device coordinates


must not exceed the (16 bit) range OxFFFF8000rox00007FFF (-32768 to 32767)
and world, and all other, coordinates must not exceed the (28 bit) range
OxF800cOoorox07FFFFFF (-134217728 to 134217727) and must also conformi to
the 16 bit device coordinate range when transformed to device coordinates.
Note also the futher restriction that world coordinates must be in the (16 bit)
range OxFFFF8000unooco7FFF (-32768 to 32767) if the PS was created with the
GPIF_SHORT format option and that it is an application responsibility to ensure
this. It will not be policed. This restriction applies to coordinates stored in retained
segments and MetaFiles. The coordinates will be truncated to 16 bits if the
GPIF_SHORT format option is used.
158 OS/2 PRESENTATION MANAGER GPI

Where only rectangular transformations are used, the 16 bit device coordinate
limits (-32768, -32768) and (32767, 32767) can be back transformed (using
Gpiconvert) to world coordinate space to obtain the world coordinate limits that
will avoid device coordinate overdow. In the more complex case, when rotation and
shear are used, the device coordinate limits must be back transformed, using
Gpiconvert,tomodelspaceandcomparedagainsttheboundarydataofthepicture
(see chapter 10). Even this relies on the viewing and the default viewing trans-
forms providing only rectangular transformations.

GPI00NVERT

Gpiconvert is an extremely useful transform function that enables an application


to transformi coordinates from any specified coordinate space to any other. This is
used, for example, by the function DisplayTextBuffer in chapter 1 to convert the
window rectangle from device to world coordinates.

A DETAILED DESCRIPTION OF THE TRANSFORMS

The remainder of this chapter provides a detailed description of the different


transform types.

Model Transform
Model transform is a picture drawing attribute that can be varied during drawing
for the purpose of picture construction. This is is the `work-horse' transfol.in that
should be used for all picture modeling and construction purposes.
Using the TRANSFORM_REPLACE, TRANSFORM_ADD, and TRANS-
FORM_PREEMPI' options, an application can, if required, construct its own model
transformi pipeline of any complexity similar to that in Figure 7-2 but consisting
only of model transform matrices. The concatenation of all the matrices in such an
application model transformi pipeline provides the value of the model transform
drawing attribute represented by the single model transfo]rm in Figure 7-2.
Note that whenever model transfo]rm is changed, this is equivalent to beginning
a new sub-picture in a new world coordinate space (see Figure 7-2).
There are three forms of model transform, all of which contribute to the model
transformi drawing attribute. These are:
1. Model Thansform itself.
This is set and queried using:
GpisetModelThansformMatrix; and
GpiQueryModel'Thansform.Matrix.
GpisetModel'ThansformMatrix will set (or push and set) the current
value of model transfo]rm drawing attribute, store a set (or push and
COORDINATE SPACES AND TRANSFORMATION 189

set) model transformi element in the currently open retained segment,


or both, depending on drawing mode. If attribute mode is AM PRE-
SERVE (see chapter 3), the push and set rather than the set veisions
of the above apply. The actual orders stored in a retained segment by
this function are illustrated in Figure 7-3. As explained above the
TRANSFORM REPIACE, TRANSFORM_ADD, and TRANS-
FORM_PREEriFToptionscontrolthewayinwhichthenewmatrixis
combined with the existing model transfo]rm. drawing attribute. Where
an element (i.e., OCODE_GSTM/OCODE_GPSTM) is being stored in
a retained segment or MetaFile, they control the flags (overwrite,
concatenate after or concatenate before) stored in the order. These
flags are applied when the segment is subsequently drawn.

RETAINED SEGRENI

GplQpons®gDent()
(Nan-Id®ntlty PS Matrix)
Internal Note that thl3
Gplset/Querys®gpent( ) > Segment ls not directly
Tran8forDHatrlx( . . s®gld. . ) Prolog vlslblo to an
application
ulil®sB recorded
ln a Hetdrlle
FIRST ELERERT >

Gpls®tMod®1Transforn Set Modal Transform


Matrix( ) Matrix Order (GS")
(AH_NOPRESERVE)

Gpls®tHod®lTrarisfordL PuBh and Set Model


Matrir( ) Tralis forD Matrix
(AH_PRESERVE) Order (GPSTH)

Gplc.11S®gp®ntMatrlx()

tsegr®nt Vlewlng TranBforn: 18 cr®at®d on Gpl0pons®gm®nt


camot b® qu®rl®d
.

Figure 7.3 Retained Segment 'Thansfo]rm Orders.


160 OS/2 PRESENTATION MANAGER GPI

2. Instance 'Thansform.
This is set using:
GpicallsegmentMatrix
Instance transform. is the name used for the model transform. matrix
specified as a parameter to GpicallsegmentMatrix. When the same
object (e.g., a wheel) is to be drawn more than once with different
positions and sizes, it can be stored once in a retained segment and
displayed by calling this segment multiple times. The instance trans-
form enables the position and size of each instance of the object to be
controlled by the matrix parameter on the individual calls.
GpicallsegmentMatrix will either `push and set' the current value of
the model transformi drawing attribute and then call the segment and
pop the old value, store a sequence of orders in the currently open
retained segment, or both, depending on drawing mode. In the re-
tained case, the orders stored are as illustrated in Figure 7-3. and
include push and set model transfol.in (GPSTM), call segment
(GCALLS), and pop (GPOP). The begin and end element orders serve
only to bracket together the group of orders identifying them as a
single element.
Note that regardless of attribute mode, in both non-retained and
retained cases the `push and set' version of set model transformi is
always generated by GpicallsegmentMatrix, and the call is always
followedbyapopfunctionthatensuresthattheoriginalvalueofmodel
transform attribute is preserved across the call.
Operation of the TRANSFORM_REpljACE, TRANSFORM_ADD,
and TRANSFORM_PREEMFT options with GpicallsegmentMatrix
is identical to that for GpisetModel'Thansfo]rmMatrix.
3. Segment Thansform.
This is set and queried using:
Gpis ets egmentThansform.Matrix; and
GpiQuerysegment'Thansfo]rmMatrix.
GpisetsegmentThansformMatrix applies only to retained segments
and does not modify the model transfo]rm drawing attribute until the
segment concerned is subsequently drawn. It creates and stores a
`push and set model transform' order (GPS'IM) in an internal prolog
at the start of an existing retained segment (see Figure 7-3). If a
segment has no intermal prolog, GpisetsegmentThansfo]rmMatrix will
create one and insert it at the start of the segment.
If TRANSFORM_REPIACE is specified with Gpisetsegment
ThansformMatrix, the existing value in the retained segment (if any)
is replaced. If TRANSFORM ADD or TRANSFORM PREEMFT are
specified,thenewvalueiscon-catenatedwiththeexistingvalueinthe
COORDINATE SPACES AND TRANSFORMATION 161

retained segment (or with an identity matrix if the segment cuITently


has no segment matrix). When the segment is drawn, the model
transform. drawing attribute is always modified by the segment trams-
formi in an additive manner (i.e., the segment model transfo]rm. matrix
is concatenated after the cument model transform matrix drawing
attribute).

Viewing Transform

Although it does satisfy certain specific requirements such as sub-picturing, the


viewingtransformistheleastusefuloftheavailabletransformsandforthema].ority
of applications it can be ignored. Viewing transform is set and queried using:
Gpi s etviewingThansformMatrix; and
GpiQueryviewing'ThansformMatrix.
Like model transform, viewing transfo]rm is also a picture drawing attribute that
can be varied during drawing for the purpose of picture construction. Unlike model
transform, however, viewing transfo]rm cannot be used with non-retained drawing
primitives outside segments; it affects only drawing prilnitives or elements that
occur inside retained or non-retained segments (i.e., between Gpiopensegment
and Gpiclosesegment). Its purpose is to provide an additional transform capable
of transforming the entire (model space) output of a segment without being
overridden by model transforms within the segment.
An example of viewing transfo]rm use would be for importing a sub-picture into
an existing picture where the sub-picture may have different page units from the
target. The size and position of the target rectangle can be used together with the
sub-picture boundary data to determine the viewing transfo]rm. required to provide
the correct transformation. This is illustrated by the function SubpictureMetaFile
in chapter 11. In this example, as in most normal uses, viewing transfo]rm provides
only rectangular transformation but it is also capable of more general transfor.in
operations (e.g., rotation) if required. This does, however, introduce complications
into certain operations such as that of converting the boundary rectangle from
model to page coordinate space.
Note that whenever viewing transfo]rm is changed for a new segment or group
of segments, this is equivalent to beginning a new sub-picture in a new model
space (see Figure 7-2).
Like segment transform, viewing transfo]rm. in a retained segment is stored in
an internal prolog at the segment start (as a set viewing transfo]rm order in this
case). However, whereas the segment transfo]rm is just a normal model transform.
that can be replaced or pre-empted by subsequent model transfol.in orders in the
segment, viewing transform is immune from any such interference from the
segment contents.
GpisetviewingThansformi does not update the viewing transfol.in drawing attri-
butes of retained segments directly, but merely updates a matrix stored in the PS
(see chapter 3). The TRANSFORM_REPI.ACE, TRANSFORM_ADD, or TRANS-
162 OS/2 PRESENTATION MANAGER GPI

FORM_PREEMPI` options control the way in which the new matrix is combined
with the existing PS matrix. The viewing transform. drawing attribute is always
updated (from the segment prolog matrix) by a replace operation when the
segment is draun.
When Gpiopensegment is issued, the PS matrix is used to update the viewing
transformdrawingattributeortoconstructa`setviewingtransform'order(GSTV)
in an internal prolog at the start of a new retained segment, or both, depending on
drawing mode (see Figure 7-3). If the PS matrix value is identity, no internal
prolog is created when a segment is created. The segment, if chained, behaves as
if it contains an implicit `set viewing transform' order with an identity matrix (i.e.,
when the segment is drawn, the viewing transfo]rm drawing attribute is reset to
identity at the start of the segment). The viewing transform drawing attribute is
alwaysresettoidentityattheendofanydrawnrootsegmentandbyGpicloseseg-
ment when drawing mode is DM_DRAW or DM_DRAWANDRETAIN (see Figure
3-1).
When creating a segment for use as a called segment, the PS viewing transform
matrix should first be reset to identity (using GpisetviewingThansformMatrix)
before issuing Gpiopensegment to ensure that no set viewing transformi order is
stored in the segment. Such an order in a called seglnent would destroy the
transform pipeline model illustrated in Figure 7-2 and for this reason is ignored.
If present, it could result in an invalid interchange file when used to create a
MetaFile.
Note that for IBM OSA Version 1.3 at least, neither the viewing transform
drawing attribute nor the retained segment viewing transfo]rm matrix value can
be queried. Also, the retained segment viewing transfo]rm matrix value carmot be
modified. This is something of a disadvantage that affects the usefulness of this
p articular transform function.

Default Viewing Transform

Default viewing transform is set and queried using:


Gpis etDefaultviewMatrix; and
GpiQueryDefaultviewMatrix.

Default viewing transform is a PS environment attribute rather than a drawing


attribute and should not, therefore, be varied during drawing. Like the other
transforms, its default value is identity. It purpose is to enable the application to
scroll and scale the entire picture in the PS page. For this reason, although capable
of operations such as shear and rotation, it is not really intended for these (with
the exception, perhaps, of 90-degree rotation).
GpisetDefaultviewMatrix always updates the default viewing transformi (envi-
ronment) drawing attribute directly. The TRANSFORM_REPIIACE, TRANS-
FORM_ADD, or TRANSFORM_PREEMFT options control the way the new rna-
trix is combined with the existing matrix as described above.
COORDINATE SPACES AND TRANSFORMATioN lee

Device Transform
It is the device transfo]rm that provides the requested page units for a particular
device. For page units of PU_PELS, its value is identity. For other page units, it is
the transformi from the page to the device that yields the required page units for
the particular device resolution. For any of the standard page units, its value is
established with the page units by:
Gpicreateps;
Gpisetps (without PS_NORESET option);
GpiplayMetaFile (with RES_RESET option); and
Cached PS allocation Gage units PU_PELS, device transfo]rm.
Identity).
Where its requirements are fully satisfied by the standard page units, an applica-
tion need not concern itself with device transform. If essential, however, it can
modify the device transfo]rm. to define its own page units. This is accomplished
using Gpisetpageviewport.
Unlike other transforms, device transfo]rm. is defined by two rectangles, those of
the page and the page viewport, with the actual matrix element values determined
as follows:
Mll = 0[2 -X1)/W
M12 = 0
M21 = 0
M22 = cr2 -¥1)/ H
M3i = xi + ive*quii - 1)
M32 = yi + i#*Or22 - 1)
(X1, Y1) and (X2,Y2) are the bottom left and top right coordinates of the page
viewport, with the top right coordinate (X2,Y2), exclusive (i.e., outside the rectan-
gle) because these are in device coordinates. W and H are the width and height of
the PS page where the page coordinates are (0,0) and (W-1,H-1). These points are
both inclusive (i.e., inside the rectangle).
This definition of device transfo]rm is illustrated in Figure 74. Like the page
viewport, which consists of a rectangular aITay of device pixels, the PS page is
viewed as a rectangular array of cells. One might assume that the center bottom
left cell (0,0) would transfo]rm to the center bottom left pel O[1,Y1) but this is
not the case. In the GPI model, the bottom left comer of the bottom left cell
(-1/2,-1#) transforms to the bottom left corner of the bottom left pel Q[1-1#,Y1-
1#). Similarly, the top right comer of the top right cell (W-|#, H-1#) transforms
to the top right comer of the top right pel (X2-14,Y2-1#). This model gives
greater accuracy when (say) the number of cells is small compared to the
number of pels.
164 OS/2 PRESENTATION MANAGER GPI

(V-I/2'II-|/2)

PAGE

(-112..-L12:)

(X2-1/2,Y2-I/2)

PACE
VIEWPORT

(Xl-1/2,Y1-1/2)

Figure 7.4 Device 'Thansformi Model.

As the page coordinates are fixed by the page dimensions on PS creation (or by
Gpisetps), page units can only be changed by modifying page viewport coordi-
nates. The page viewport is set and queried using:
Gpisetpageviewport; and
GpiQuerypageviewport.
Note that page viewport is not automatically the same as the rectangle returned
from WinQuerywindowRect and neither the page nor the page viewport are
clipping rectangles. These two rectangles merely serve to define the device trans-
formi that provides the required page units.
As mentioned earlier, either or both page dimensions may be defaulted causing
them to be set to the corresponding default device dimensions or, in the case of a
display, the display screen size. In the case of PU_ARBITRARY page units, the size
of one dimension will be constrained, where necessary, to ensure that the picture
aspect ratio is preserved.
The system will compute page viewpori coordinates for existing page units even
when Gpisetpageviewport has not been issued. These can then be queried and
used in the calculation of new page viewpord values or used at any time with
Gpisetpageviewpord to restore the page units to their original value.
It is recommended that, wherever possible, applications should use standard
page units rather than defining their own. This is because application defined page
units are not stored in either a MetaFile or an OD_QUEUED (PM_Q_STD) print
file (see chapters 11 and 12).
COORDINATE SPACES AND TRANSFORMATION 165

With one exception, page viewport (i.e., device transform) should not be used for
operations such as scaling and scrolling. The exception is for PU_ARBITRARY
page units where it is required to scale the picture to fit the window as it is sized.
The function ScaleTOFitwindow in Figure 7-5 illustrates how to scale a PU AR-
BITRARY presentation space to fit the window ®y default it is scaled to- the
display screen size rather than the maximized window size as doculnented).

Device Transform Translation Removal


As pointed out above, by default (0,0) in the page will not always transfo]rm. exactly
to (0,0) in device coordinates. When the resolution of the device is high compared
to that of the page, a small positive translation will occur in both x and y directions.
For example, if there are three pels for each page unit then (0,0) in the page will
transform to the center of the bottom left 3x3 cell, that is, to point (1,1) on the
device. This does not normally present a problem unless a device happens to
require every available pel for some particular operation. For example, with some
devices this translation can cause the maximum number of characters per row to
be reduced from 80 to 79. In theory, a similar problem can also exist vertically but
this is less likely and has never been reported.
If this does create a problem there is a choice of solutions.
• Change to higher resolution page units (e.g., from PU_LOENGLISH
to PU_HIENGLISID or increase the page dimensions for PU ARBI-
TRARY page units. This will increase the resolution of the page
making it closer to that of the device.
• Apply a suitable scaling factor using GpisetDefaultviewMatrix to
scale the world coordinates down, increasing the resolution of world
coordinate space. The world coordinates specified for drawing would
then, of course, need to be increased by the same factor. The exact
scale factor used is not critical but should be sufficient to make the
resolution of world coordinates the same as, or greater than, that of
the device coordinates.
® Apply a correction to the device transfo]rm. to remove the unwanted
translation as illustrated by the function Remove'Thanslation in Fig-
ure 7rfe. This should also work successfully when printing via the
spooler using data type PM_Q_RAW. If the data type is PM_Q_STD
an equivalent correction can be achieved using the `XLT=' fhint
Queue Hocessor parameter (see Appendix 2).
166 OS/2 PRESENTATION MANAGER GPI

scltofl't.c */
OL ScaleTOF1.twi.ndow(HPS hps, HWND hwnd, PRECTL prclpvlni.t)

Scale a pi.cture 1.n a PS wl.th PU_ARBITRARY page unl.ts to fl.t the wi.ndow
when l.t has been sl.zed.

i.nputs: hps Ps handle


hwnd cli.ent wi.ndow handle
prclpvlni.t a poi.nter to the I.ni.tial page vl.ewport (queri.ed before
Gpi.Setpagevi.ewport has been i.ssued)

B00L fRet /* B00L return code


SIZEL si.zlps /* PS sl`ze
RECTL rclw1.nd /* wl.ndow rectangle
P0INTL ptlTR /* TR coords of l.deal max wl.ndow
FIXED fxscaleFactor /* scale factor
LONG 1 PvpHei.ght /* new page vi.ewport hei.ght
LONG 1 PvpW1.dth /* new page vi.ewport wi.dth
RECTL rclpvp /* new page RECTL values

/* query wi.ndow coordi.nates


fRet = Wl.nQueryw1.ndowRect( hwnd /* -wi.ndow handle
&rclwl'nd /* -returned coordi.nates
in
l'f (fRet) /* query PS sl.Ze
fRet = Gpl.Queryps( hps /* -PS handle
&sl'zlps /* -returned si.ze
) !-GPI_ERROR;

/* set page vl.ewport to


l'f (fRet) /* maxl.ml.zed si.ze
fRet = Gpi.Setpagevi.ewport( hps /* -PS handle
prclpvlnl't /* -page vi.ewport
);

ptlTR.x = sl.zlps.cx-1; /* convert PS page dl.mensl.ons


ptlTR.y = sl.zlps.cy-1: /* to devi.ce coordl.nates to
l'f (fRet) /* gi.ve i.deal maxi.mi.zed wi.ndow
fRet = Gpi.Convert( hps /* -PS handle
CVTC_PAGE /* -source
CVTC_DEVICE /* -target
1L /* -count of poi.nts
&ptlTR /* -pol'nts
in

/ ****************************************************************************** I
/**/
/* If current wi.ndow x/y > i.deal wi.ndow maxl.mi.zed x/y aspect rati.o */
/* calculate scale factor to fi.ll wi.ndow verti.cally */
1* else *1
/* calculate scale factor to fl.11 wi.ndow hori.zontally */
/**/
I ****************************************************************************** 1

l.f (((rclwi.nd.xRi.ght*Oxl0000)/rclwl.nd.yTop) > ((ptlTR.x*Oxl0000)/ptlTR.y))


fxscaleFactor = (rclw1.nd.yTop * Oxl0000) / ptlTR.y;
else
fxscaleFactor = (rclwi.nd.xRi.ght * Oxl0000) / ptlTR.x;

Figure 7.5 ScaleTOFitTowindow Function.


COORDINATE SPACES AND TRANSFORMATION 167

/ ****************************************************************************** /
/**/
/* Use scale factor to calculate new page vl.ewport hel.ght and wi.dth then */
/* calculate new page vi.ewport coordi.nates. */
/**/
1 ****************************************************************************** /

1Pvpwi.dth = (prclpvlni.t->xRi.ght -prclpvlni.t->xLeft)*fxscaleFactor/Oxl0000:


lpvpHei.ght = (prclpvlnl.t->yTop -prclpvlni.t->yBottom)*fxscaleFactor/Oxl0000;
rclpvp.xLeft = (lpvpwl.dth / sl.zlps.cx -1) / 2;
rclpvp.yBottom = (1PvpHel.ght / sl.zlps.cy -1) / 2;
rclpvp.xRi.ght = rclpvp.xLeft + lpvpwi.dth;
rclpvp.yTop = rclpvp.yBottom + lpvpHel.ght;

1.f (fRet) /* set the new page vl.ewport */


fRet = Gpi.Setpagevl.ewport( hps /* -PS handle */
&rclpvp /* -page vl.ewport */
);

return ( fRet ) ;
)

Figure 7.5 (continuecL)

removetr.c */
OL RemoveTranslati.on(HPS hps)

Remove the translatl.on component from the devl.ce transform */


*/
i.nputs: hps PS handle */
*/

RECTL rclvi.ewport /* page vi.ewport


B00L fRet /* B00L return code
P0INTL ptlcoord /* coordi.nate poi.nt

ptlcoord.x = OL; /* convert (0,0) from page to


ptlcoord.y = OL; /* devi.ce space
fRet = Gpi.Convert( hps /* -PS handle
CVTC_PAGE /* -source
CVTC_DEVICE /* -target
1L /* -count
&ptlcoord /* -coordl.nate pol.nt
n
l'f (fRet) /* query page vi.ewport
fRet = Gpl.Querypagevl.ewport( hps /* -PS handle
&rclvi.ewport /* -page vl.ewport rectangle
n
rclvi.ewpcirt.xLeft -= ptlcoord.x; /* adjust the page vi.ewport
rclv1.ewport.xRl.ght -= ptlcoord.x; /* coordi.nates to remove any
rclvi.ewport.yBottom -= ptlcoord.y; /* translatl.on and set the
rclvi.ewport.yTop -= ptlcoord.y: /* page vi.ewport
l'f (fRet)
fRet = Gpl.Setpagevi.ewport( hps /* -PS handle
&rclv1.ewport /* -page vi.ewport rectangle
);

retu rn ( f Ret ) ;

Figure 7.6 Remove'Thanslation Function.


Clipping And Regions

APPLICATION CLIPPING FUHCTIOHS

The GPI provides four different application clipping functions providing both
picture and environment clipping. These provide clipping to a single rectangle, a
shape defined by a number of rectangles, or an arbitrary shape of almost unlimited
complexity. By default, each of these functions provides no clipping.
The four GPI clipping functions are:

Viewing Limits

The viewing limits define a single clipping rectangle in model space. This is a
primitive drawing attribute that can be varied as the picture is drawn. Its purpose
is to enable part of a picture to be clipped to a single rectangle in model space
during picture construction® Points on all boundaries of the viewing limits are
inclusive (i.e., inside the rectangle) and are therefore unclipped. See chapter 3 for
a description of the viewing limits attribute functions.

Graphics Field

The graphics field defines a single clipping rectangle in the PS page. This is an
environment attribute that should be set initially and not varied as the picture is
drawn. Its purpose is to enable the entire picture to be clipped to a single rectangle
in the page. Points on all boundaries of the graphics field are inclusive (i.e., inside
the rectangle) and are therefore unclipped. The graphics field is set and queried
using:

168
CLIPPING AND REGIONS leo

GpisetGraphicsField

GpiQueryGraphicsField

Note that graphics field does not confo]rm to the MetaFile interchange architecture
and, although it can be used in MetaFiles for interchange with other OSA
workstations, it should not be used when recording MetaFiles for interchange with
other products (see chapter 11).

Clip Path

The clip path defines an arbitrary clipping shape of any complexity (subject to
intermal implementation limits). A clip path is defined initially as a normal path
in world coordinates using normal GPI drawing primitives. Once `output' and
converted to a clip path, it becomes fixed in device coordinates and is unaffected
by subsequent transformi changes. Clip path is a picture clipping object that can
be varied as the picture is drawn. Its purpose is to enable part of, or the entire
picture, to be clipped to any complex shape. Points on all boundaries of the clip
path are inclusive (i.e., inside the clip path) and are therefore unclipped. See
chapter 3 for a further description of the clip path.

Clip Region

The clip region provides a clip boundary defined by one or more rectangles in
device space. This is a PS environment attribute that should be set initially and
not varied as the picture is drawn. Its purpose is to enable the entire picture to be
clipped to a complex shape defined by a number of rectangles in device space. As
it is defined in device space, clip region is not subject to rounding eITors that may
occur with other clipping functions. Atypical use is to provide the clipping required
by the newly exposed area that must be redrawn after (say) a scroll operation is
performed using GpiBitBlt.
Note that the clip region does not confo]rm to the MetaFile interchange architec-
ture and although it can be used in MetaFiles for interchange with other OSA
workstations,itshouldnotbeusedwhenrecordingMetaFilesforinterchangewith
other products (see chapter 11).
A further description of region and clip region functions is provided below.

REGIONS AHD CLIP REGIONS

A region is an object defined by one or more rectangles in device coordinates.


Regions are most commonly used to provide clipping but can also be used for area
fill. The region functions provide an application with a means of creating and
modifying regions and clip regions and filling a region using the AREABUNDIE
attributes.
All rectangles used with region and clip region functions are specified in device
170 OS/2 PRESENTATION MANAGER GPI

coordinates, are inclusive at the bottom and left coordinate boundaries, and
exclusive at the top and right coordinate boundaries (i.e., the bottom and left
boundaries are inside the rectangle and are unclipped; the top and right bound-
aries are outside the rectangles and are clipped).
A region must be explicitly selected as a clip region to enable it to be used for
clipping.

Region Functions

When a region is initially created, its shape is determined by an array of one or


more rectangles. Regions are created and destroyed using:
GpicreateRegion; and
GpiDestroyRegion.
Regions can be combined and modified using:
GpicombineRegion;
GpioffsetRegion; and
GpisetRegion.
Functions also exist to query whether two regions are identical, to query whether
a point or rectangle lies inside the region, to return the bounding rectangle of a
region, and to return an alTay of rectangles defining the region shape. These are
performed using:
GpiEqualRegion;
GpiptlnRegion;
GpiRectlnRegion;
GpiQueryRegionBox; and
GpiQueryRegionRIcts.
A region can be filled using the AREABUNDLE attributes by:
GpipaintRegion

clip Region Functions

A region is converted to a clip region using:


GpisetclipRIgion
GpisetclipRegion returns the handle of the previous clip region (or NULL). While
a region is selected as the clip region, the normal region functions (above) are
invalid for that region.
Clip regions can be modified by excluding or intersecting with a specified
rectangle using:
CLIPPING AND REGIONS 111

GpiExcludeclipRectangle; and
GpilntersectclipRectangle.
These functions automatically create a clip region if one does not already exist
(such a region does not need to be destroyed by the application when no longer in
use).
Functions also exist to query the bounding rectangle of a region and to query the
handle of the currently selected clip region. These are:
GpiQueryclipBox; and
GpiQueryclipFlegion.

Region Complexity

A number of the above region and clip region functions return the complexity of
the region or clip region as one of:
RGN_NULL The region or clip region is a null rectangle (no clip-
ping).
RGN_RECT The region or clip region is a simple rectangle.
RGN_COMPIEX The region or clip region is a complex shape de-
fined by two or more rectangles.
Orders, Elements, and Segments

DRAWING ORDERS

A drawing order is a sequence of bytes in a graphics segment representing a


particular primitive or attribute drawing function. Each drawing primitive or
primitive attribute recorded in a retained graphics picture or MetaFile, is stored
as one or more graphics orders. In all cases, drawing orders are contained in
graphics segments either in PS segment store as part of a retained picture or in a
MetaFile. A drawing order is the smallest complete unit of a graphics segment.
Orders have a 1-byte order code and can be classified into the following groups,
based on order length:
• Fixed 1-Byte Orders.
• Fixed 2-Byte Orders.
• Long Orders.
• Extended Orders.

Fixed 1-Byte Orders

There are only two 1-byte orders. They are:


Byteo = OxOO GNOP1 0Vo-Operation); and

Byteo = OxFF GESD qnd of Symbol Definition).


GESD applies to outline font character definitions only. An order is a 1-byte order
if its order code is either OxOO or OxFF.

172
ORDERS, ELEMENTS, AND SEGMENTS 113

F[xed 2-Byte Orders


Fixed 2-byte orders have the form:
Byteo = order code with bit7=0 & bit 3=1 (i.e. 0-1-)
Bytel = order data
An order is a 2-byte order if the order code has bit7=O and bit3=1. Examples of
2-byte orders are:
Byteo = Oxl8 GSIJT (Set Line Type)
Bytel = Oxol dotted

Byteo = Ox68 GBAR ®egin Area)


Bytel = Ox40 draw boundary using alternate mode fill

Long Orders
These are orders of variable length between 3 and 257 bytes. Long orders have the
form:
Byteo = order code (not 1-byte, 2-byte or extended)
Bytel = length of following data (255)
Byte2+ order data
An order is a long order if the order code is neither a 1-byte nor an extended order
code, and does not satisfy the criteria for a 2-byte order (i.e., order code is not OxOO,
OxFF, OxFE and bit7=1 or bit3=0). Examples of long orders are:
Byteo = Ox81 GCLINE qine at Current Position)
Bytel = length of following data
Byte2+ xy coordinate points

Byteo = OxD6 GBBLT OvC BitBlt)


Bytel = length of following data
Byte2-n Flags, mix, source bitmap, etc.

Byteo = OxD5 Escape (used in MetaFile only)


Bytel = length of following data
Byte2 = Ox80 Type = Registered
Byte3 = OxO1 (Set Pel)
Byte4-n order data
114 0S/2 PRESENTATION MANAGER GPI

Byteo = OxD5 Escape (used in MetaFile only)


Bytel = length of following data
Byte2 = Ox80 Type = Registered
Byte3 i Ox02 q3itBlt)
Byte4-n order data
MetaFiles use long escape orders (e.g, set pel above) to record functions not defined
by the interchange architecture (see chapter 11).

Extended Orders
These are orders that have a variable length of up to 64K bytes. They are
identified by a unique order code (OxFE) followed by an order qualifier, providing
the real order code, and a 2-byte length field. Note that bytes 2 and 3 of the order,
which contain the 2-byte length field, have the high order byte first; this is the
reverse of the normal 2-byte numerical representation. Extended orders have the
form:
Byteo = OxFE (extended order)
Bytel = order qualifier (i.e., actual order code)
Byte2 = length of following data (MS byte)
Byte3 = length of following data (LS byte)
Byte4-n order data
An order is an extended order if its order code is OxFE. Examples of extended
orders are:
Byteo = OxFE (extended order)
Bytel = OxC3 GCHST (Character String at Given Position)
Byte2 = length (MS byte)
Byte3 = length (LS byte)
Byte4-n xy position, character string

Byteo = OxFE (extended order)


Bytel = Ox83 GCCHST (Character String at Current Position)
Byte2 = length (MS byte)
Byte3 = length (LS byte)
Byte4-n character string
ORDERS, ELEMENTS, AND SEGMENTS 115

Byteo = OxFE (extended order)


Bytel = OxF0 GCHSTE (Character String Extended at Given
Position)
Byte2 = length (MS byte)
Byte3 = length (LS byte)
Byte4-n xy position, flags, rectangle, string, increments, etc.

Byteo = OxFE (extended order)


Bytel = OxBO GCCHSTE (Character String Extended at Current
Position)
Byte2 = length (MS byte)
Byte3 = length (LS byte)
Byte4-n flags, rectangle, string, increments, etc.

Byteo = OxFE (extended order)


Bytel = OxD5 Escape
Byte2 = length (MS byte)
Byte3 = length (LS byte)
Byte4 = OxOO Unregistered
Byte5 = Oxol MetaFile Create Logical Color Table
Byte6-n order data
MetaFiles use extended escape orders (e.g., Create Logical Color Table above) to
record functions not supported by the interchange architecture and to record
changestotheenvironmentorresourcesthatoccurinthepicturedata(seechapter
11).

Order Buffers

Although normally used within elements and segments, order buffers can be
transferred between application memory and the presentation space using:
GpifutData; and
GpiGetData.
GpiputData can be used to draw a buffer of orders, store them in a retained
segment, or both, depending on the drawing mode. The buffer need not contain a
whole number of complete orders. If there is an incomplete order at the end of the
buffer, then this will be returned to the application unprocessed enabling the
116 0S/2 PRESENTATION MANAGER GPI

application to concatenate this in front of the subsequent data. GpiGetData is used


to retrieve a buffer of orders from a retained segment. Like GpiputData, the
returned data may not contain a whole number of complete orders.

ELEMENTS

An element is the smallest editable unit of a graphics segment and consists of


either a single order, or, one or more complete orders within an element bracket.
For example:
GBEL (Begin Element);
GPSTM Gush and Set Model 'Thansform);
GCALLS (Call Segment);
GPOP (Pop); and
GEEL (End Element).
The purpose of the Begin and End Element is to bracket together a group of related
orders enabling them to be edited as a single entity in a retained segment. For
example, GpicallsegmentMatrix generates the entire sequence of orders shown
above. As this sequence of orders is generated by a single GPI function, they fo]rm
a single element, which can, for example, be subsequently deleted by a single
GpiDeleteElement call.
Each element has a type and description (which can be null). For elements
consisting of a single order, these are implicit. For elements defined by a Begin
Element-End Element bracket, these fo]rm. part of the Begin Element order.
Elements may be generated by the system, as described above, or an application
may define its own. Application defined elements should specify a type value in
the range Ox81000000-OxFFFFFFFF. Values outside this range are reserved for
system use.
Functions similar to GpiputData and GpiGetData exist for setting and retriev-
ing an order buffer containing a single complete element. These are:
GpiElement; and
GpiQueryElement.

GRAPHICS SEGMENTS

All pictures stored in a retained PS segment store or a MetaFile are constructed


from one or more graphics segments, with each segment containing one or more
elements (or orders). A graphics segment is created by issuing the GPI functions
required to define the contents of the segment between:
Gpiopensegment; and
Gpiclosesegment.
ORDERS, ELEMENTS, AND SEGMENTS lil

A segment may be retained (i.e., stored in retained PS segment store) or non-re-


tained (i.e., the primitives are drawn as it is defined and inrmediately discarded)
depending on drawing mode (see below).
The structure of a graphics segment structure is illustrated in Figure 9-1. Each
segment has a segment id, a number of segment attributes, an (optional) internal
prolog, and the segment body containing the elements (i.e., groups of primitive
drawing and attribute orders).
Segments with no internal prolog have implicit viewing and segment transforms
of identity. An internal prolog is added, as necessary, to a retained segment by
GpisetsegmentThansformMatrix. The prolog is termed an `intemal prolog' be-
cause it is not visible to an application and cannot be edited with the elements in
the body of a retained segment. The internal prolog will, however, be visible as a
normal prolog (complete with prolog segment attribute and end prolog order) if the
segment is recorded in a MetaFile. Application defined prologs (with end prolog
orders and prolog segment attribute as described in the IBM Graphics Architec-
ture Reference) are not currently supported by the GPI except within MetaFiles.
An End Holog order passed with GpiputData, for example, will be treated as a
No-Op.

S®gr®nt Attrlbut®s

11
ATTh I)ETECTABLE
ATm_vlslBIE
AT" CHAINED
Am_I)vNAMlc
Am_FASTCRAIN
Arm_pROp_I)ETECTA814E
Am_pRop_vlslBIE

Vlowlng TranBforn Hatrlx

Sogm®nt (Hod®1) Tran.form


Matrix

Graphlca El®D®ntB (order.)

Day include GCALI,s


(call to another !egpent)

Figure 9.1 Graphics Segment Structure.


178 OS/2 PRESENTATION MANAGER GPI

The segment transform can be modified and queried using


GpisetsegmentThansformMatrix and GpiQuerysegmentThansformMatrix but
currently, the viewing transform, once established for a retained segment, cannot
subsequently be modified or queried at all for that segment.
The function CreateRItainedsegment in Figure 9-2 illustrates the creation of a
retained (chained) graphics segment followed by a draw chain operation.

crretseg.c */
L CreateRetai.nedsegment(HPS hps, LONG Isegld)

Create a retai.ned (chai.ned) graphi.cs segment (whi.ch i.s appended to the


chai.n) and draw the chai.n. It is assumed that the PS drawl.ng mode may not
be DM_RETAIN on entry.

i.nputs: hps Ps handle


lsegld Segment ID

#defi.ne SEGCHARS "Retai.ned Segment Characters"


#defl.ne NSEGCHARS (LONG)(si.zeof(SEGCHARS)-1)

B00L fRet /* B00L return code


B00L fRets = FALSE /* B00L return code
P0INTL ptlpol'nt /* coordi.nate point

/* set drawl.ng mode to retain


fRet = Gpi.SetDrawl.ngMode( hps /* -PS handle
DM_RETAIN /* -mode = retain
in

if (fRet) /* set chained inl.tial seg attr


fRet = Gpi.Setlni.ti.alsegmentAttrs( hps /* -PS handle
ATTR_CHAINED /* -attri.bute
ATTR_ON /* -value
n
if (fRet) /* open segment
fRet = fRets = Gpi.Opensegment( hps /* -PS handle
lsegld /* -segment i.d
in

nt.x -100L:
nt.y -100L;
/* draw to segment */
fRet = (B00L)Gpl.Charstrl.ngAt( hps
&ptlpo,tnt
NSEGCHARS
SEGCHARS
in

l'f (fRets) /* close segment


fRet = Gpl.Closesegment(hps) && fRet;

l'f (fRet) /* draw chai.n


fRet = GpiDrawchal.n(hps);

return ( f Ret ) :

Figure 9.2 CreateRetainedsegment Function.


ORDERS, ELEMENTS, AND SEGMENTS 119

CHAINED AHD CALLED SEGMENTS

The GPI allows the entire graphics picture to be stored in, and redrawn from, a
Normal-PS segment store. This is called `retained graphics.' The GPI retained
graphics model defines a picture as a single chain of one or more retained graphics
segments. A segment is chained if its ATI`R_CrlAINED segment attribute is set.
A chained segment is sometimes called a root segment. Unchained retained
segments may also exist and may be drawn individually by the application using
GpiDrawsegment, called from other chained or unchained segments, or called
directly by an application using GpicallsegmentMatrix.
A typical retained segment store stmcture containing both root (chained) and
called (unchained) segments is shown in Figure 9-3, which also illustrates the
segment drawing functions :
GpiDrawchain;
GpiDrawFrom; and
GpiDrawsegment.

RETAINEI) SEGRENT STORE

SEGRENT CHAIN CALLED SEGMENTS


(ROor sEGMENTs)

Figure 9.3 Retained Segment Store Example.


180 0S/2 PRESENTATION MANAGER GPI

GpiDrawchain draws the entire segment chain including all segments called
directly and indirectly from the root segments. GpiDrawFrom draws a range of
segments in the chain from a specified first to a specified last segment. All
segments called directly and indirectly from the drawn root segments are also
drawn. The first segment must be in the chain and neither first nor last segment
id may be specified as zero. If the specified last segment does not appear
between the first segment and the end of the chain, it is not an eITor; drawing
continues to the end of the chain. GpiDrawseglnent draws a single specified
segment including all segments called directly and indirectly from it. The
specified segment may be chained or unchained but its id may not be specified
as zero.
When using GpiDrawFrom or GpiDrawchain, the position of a root segment in
the chain determines whether it is drawn on top of, or beneath the other segments
in the chain and is called the Segment nriority. The segment drawn last in the
chain is displayed on top of all the others and therefore has highest priority. Each
new segment that is created is added to the end of the chain. The priority of a
segment can be queried and changed using:
GpiQuerysegmentl}riority; and
Gpisetsegmentllriority.
GpiQuerysegmentFlriority specifies a reference seglnent id together with either
LOWER_PRI or HIGRER_PRI and the function returns the id of the segment
immediately before or immediately after the reference segment (or zero if the
reference segment is at the start or end of the chain).
Gpisetsegmentnriority specifies the id of both a target and reference segment
and specifies either LOWER_PRI or HIGHER_PRI to indicate where the target
should be positioned relative to (i.e., immediately before or immediately after) the
reference segment. If LOWER_PRI is specified with a reference segment id of Zero,
then the target is given highest priority in the chain (i.e., positioned at the end of
the chain). If HIGHER_PRI is specified with a reference segment id of a zero, then
the target is given lowest priority in the chain (i.e., positioned at the start of the
chain).
The segment chain structure for a MetaFile is similar to that for segment store.
The main difference is that called segments in an imported MetaFile may be
chained or unchained (as permitted by the architecture) whereas those in the GPI
PS segment store must be unchained.

DRAWING MODES

GPI primitive drawing and attribute functions are either drawn immediately,
stored as elements in the currently open retained segment, or both, depending on
the PS drawing mode (i.e., draw, retain, or draw and retain). Drawing mode is
controlled by:
GpisetDrawingMode
ORDERS, ELEMENTS, AND SEGMENTS 181

which specifies the drawing mode for the PS as one of:


DM_DRAW;
DM_RETAIN; and
DM DRAWANDRETAIN.
While these determ.ine the actual drawing mode for chained segments, these
modes are overridden for unchained segments and functions issued outside a
segment bracket. Unchained segments (on the assumption that they will be called)
are always constructed in retained mode regardless of current drawing mode. GPI
functions issued outside a segment bracket are always drawn ilnlnediately, re-
gardless of current drawing mode.
In addition, a small number of functions totally ignore the drawing mode. These
are always drawn immediately and never stored in a retained segment. They are:
GpipaintRegion;
GpiBitBlt Out not GpiwcBBitBlt);
Gpisetpel; and
All WinDraw functions (e.g., WinDrawText).

SEGMENT ATTRIBUTES

Segments have a number of properties called segment attributes (see Figure 9-1)
that each have a Boolean value of AITR_ON or ATI`R_OFF. In addition, the PS
contains a set of `initial segment attributes' that determine the initial segment
attribute values for a newly created segment at the time it is first opened. The
`initial segment attributes' of the PS can be set and queried using:

Gpisetlnitials egmentAttrs; and


GpiQuerylnitialsegmentAttrs.
The segment attributes of a specified retained segment can be set and queried
using:
GpisetsegmentAttrs; and
GpiQuerysegmentAttrs.
The segment attributes are as follows:

ATTR DETECTABLE

The segment is enabled for the detection of retained correlation hits (see
chapter 10).
182 0S/2 PRESENTATION MANAGER GPI

AITR VISIBLE

The segment is visible.

ATTR CHAINED

The segment is chained. Setting or resetting this attribute for an existing retained
segment causes the segment to be added to or removed from the segment chain.

ATTR DYNAMIC

The segment is dynamic (see below).

ATTR FASTCHAIN

The segment is fast chained. This is a performance hint allowing the system to
omit the attribute reset that otherwise occurs at the start of each root segment as
it is drawn. The ATI`R_FASTCHAIN attribute applies to chained (root) segments
drawn using GpiDrawchain and GpiDrawFrom.
If fast chaining is specified then the application undertakes to set every attri-
bute used within the segment to the required value before it is used. It is good
practice to set fast chaining off for the first segment in the chain at least, or else
issue GpiResetps (to ensure that the attributes are reset) before each
GpiDrawchain or GpiDrawFrom function call is issued. Failure to do this can give
strange effects. For example, if all segments are fast chained with no reset
performed, then one segment setting the model transfo]rm with some translation
can cause the picture to move progressively across the screen (and eventually out
of view) each time GpiDrawchain is issued.
Note also that fast chaining does not guarantee that attributes will not be
reset-it merely gives the system this option. In a future implementation, the fast
chaining attribute could well be ignored such that attributes are always reset at
the start of each root segment. This would still represent a valid implementation
of the architecture. An application should therefore never rely on the inheritance
of non-default attribute settings from one chained segment to another.

ATTR PROP DETECTABLE

The segment will propagate the ATI`R_DETECTABLE attribute to any segment it


calls.

ATTR PROP VISIBLE

The segment will propagate the ATI`R_VISIBLE attribute to any segment it calls.

SEGMEIITS WITH ZERO ID

In general, every retained segment in segment store must have its own unique
segment id. The one exception to this rule is for segments with an id of zero that
can occur more than once in the segment chain. Whereas Gpiopensegment
ORDERs, ELEMENTs, AND SEGMENTs lee

specifying a non-zero segment id will reopen any existing retained segment with
that id, if the id is zero, a new segment will always be opened. Segments with zero
id have the following restrictions:
• They cannot be edited.
• They must be chained.
• They cannot have their segment transfo]rm set or queried.
• They cannot have their segment attributes set or queried.
• They cannot have their segment priority set or queried.
• They cannot return a coITelate hit.
• They cannot be specified with GpiDrawsegment or GpiDrawFrom.
Segments with a zero id can be drawn by GpiDrawchain or GpiDrawFrom as part
of the segment chain and will contribute to boundary data.
Any primitive or attribute functions issued outside a segment bracket when
recording a MetaFile are recorded in the MetaFile as segments with an id of zero.
The function SubpictureMetaFile (in chapter 11), for example, illustrates the
use of Gpiopensegment with a zero segment id for the purpose of setting the
viewing transform matrix attribute before clearing the background rectangle.

HOH-RETAINED SEGMENTS

A non-retained segment is a group of drawing primitive and attribute functions


issued within a Gpiopensegment - Gpiclosesegment bracket in DM DRAW
mode. Although not immediately apparent, there are certain advantages ii main-
taining this segment structure, even for non-retained drawing.
• If the AITR_FASTCIIAIN initial segment attribute for the PS is not
set, Gpiopensegment will perform an implicit attribute reset opera-
tion.
• Gpiopensegment allows the viewing transfo]rm matrix attribute to
be initialized from the PS and the Gpiclosesegment causes it to be
reset back to identity.
• If the output is being recorded in a MetaFile, the non-retained
segments (complete with segment id and attributes) will be recorded
in the MetaFile.
•Anon-retainedpictureconstructedusingnamedsegmentscaneasily
be converted for retained operation in the future.

DRAW CONTROLS

The PS has a number of draw controls each with a Boolean value of DCTL ON or
DCTL_OFF. These can be set and queried using:
GpisetDrawcontrol
GpiQueryDrawcontrol
184 OS/2 PRESENTATION MANAGER GPI

The draw controls are as follows:

DCTL ERASE

This causes an implicit erase to be performed before any GpiDrawsegment,


GpiDrawFrom, or GpiDrawchain operation.

DCTL DISPLAY

This causes output to be visible on the device. If this control is not set, no output
is displayed. GpiErase is unaffected by this attribute.

DCTL BOUNDARY

This enables boundary accumulation (see chapter 10).

DCTL DYNAMIC

This causes dynamic segments to be implicitly removed and redrawn around any
GpiDrawFrom or GpiDrawchain operation (see below).

DCTL COPRELATE

This enables correlation for GpiputData, GpiElement, GpiplayMetaFile and all


non-retained drawing primitives.

STOP DRAW

Many GPI graphics drawing operations can take a considerable time to complete
and should normally be performed on a separate thread from that used for
message queue processing. For most GPI functions, it is invalid to use the same
PS on more than one one thread simultaneously. The one exception to this is
GpisetstopDraw, which enables any of the following functions to be terminated
(with a logged waming):
GpiDrawsegment;
GpiDrawFrom;
GpiDrawchain;
GpiDrawDynamics;
GpiplayMetaFile; and
GpifutData.
A draw operation would normally be terminated (and perhaps restarted with
different data) in response to an event on the message queue. A GpisetstopDraw
ORDERS, ELEMENTS, AND SEGMENTS 1&5

request to set the `stop draw' condition must be followed by a subsequent


GpisetstopDraw to clear this condition before further drawing can occur. A
semaphore or some other synchronization mechanism will normally be required
to synchronize setting and resetting the `stop draw' state with stopping and
restarting drawing on a separate asynchronous thread.

DYNAMIC SEGMENTS

The dynamic segment attribute (ATTR_DYNAMIC) is provided for interactive


retained segment operations, allowing segments on a display screen to be rapidly
removed and redrawn without disturbing the underlying picture. Dynamic seg-
ments are intended for such operations as dragging and.rubber banding.
The ATI'R DYNAMIC segment attribute applies only to chained segments and
is ignored f5r unchained segments and segments drawn individually using
GpiDrawsegment. Dynamic segments are not recorded in a MetaFile. A segment
called directly or indirectly from a dynamic segment inherits the dynamic segment
attribute. Dynamic segments have the following properties.
Regardless of their position in the chain, dynamic segments are drawn last, on
top of the remainder of the picture, with foreground mix of FM_XOR (i.e., exclu-
sive-OR) mode and background mix of BM_LEAVEALONE (i.e., transparent). Mix
values specified within the dynamic segments are ignored.
Dynamic segments are drawn using GpiDrawDynamics and removed using
GpiRemoveDynamics. Their contents must not be modified while drawn, even if
not actually visible, or problems will arise during their removal. To modify their
contents, they must be removed, updated, and then redrawn. GpiRemoveDynam-
ics can specify a segment range, allowing removal to be restricted to only those
segments affected by the update. If a range has been previously established by
GpiRemoveDynamics, then GpiDrawDynamics redraws only this previously es-
tablished range, otherwise it redraws all dynamic segments. The range is import-
ant and must include all dynamic segments affected by the update, even if these
are not actually visible. This range does not allow a subset of the dynamic
segments to be visible; all dynamic segments (or none) must be visible after a draw
operation.
Dynamic segments are implicitly removed before, and replaced after, any
GpiDrawFrom or GpiDrawchain if the DCTL_DYNAMIC draw control is set. The
range established by GpiRemoveDynamics is ignored for this implicit redraw; all
dynamic segments are redrawn.
GpiDrawDynamics can be inte]mipted (and stopped) by issuing
GpisetstopDraw (SDW_OFF) on a different thread. This would apply if, for
example, the cuITent GpiDrawDynamics operation was invalidated by a new event
on the message queue requiring a new update and redraw. Even if
GpiDrawDynamics is stopped before completion, GpiRemoveDynamics will still
remove the correct amount of dynamic segment data from the screen and no more.
GpiRemoveDynamics (explicit or implicit) cannot be stopped using
GpisetstopDraw.
186 0S/2 PRESENTATION MANAGER GPI

If the AITR_FASTCIIAIN attribute is used for the dynamic segments, it is


important that the attributes (e.g., model transfo]rm matrix) are reset before
processing these segments, either by issuing GpiResetps or by ensuring the
ATI`R_FASTCHAIN segment attribute is reset at least for the first dynamic
segment in the chain.
Dynamic segments can be positioned anywhere in the segment chain but, for
best performance, should be near the start of the chain.

SEGMENT EDITING

The GPI provides functions for editing the contents of existing retained segments.
These allow deletion, insertion, and replacement of elements in the cuITently open
retained segment.
To assist editing, label elements with numerical label values can be used to mark
reference points in the segment. A label element is similar to the segment tag
element used for correlation (see chapter 10) and like the segment tag, produces
no output to the device when drawn. Label elements are normally stored in the
segment at creation time using:
GpiLabel
To edit an existing retained segment, the segment is reopened by specifying its id
with:
Gpiopensegment
Many segment editing operations use the element pointer. The element pointer
starts at zero and increases by one for each element from the start of the segment.
Elements can be replaced or inserted in the segment at the cument element
pointer position using any of the normal drawing primitive and attribute functions
(including GpiBeginElement, GpiEndElement, and GpiElement).
On reopening a segment, the element pointer position is reset to zero, which is
immediately in front of the first element, and is incremented by one each time an
element is inserted or replaced at the current element pointer. Note that when the
current element pointer position is zero, which is before the first element, a new
element can be inserted but not replaced.
The element pointer value can be set and queried using:
GpisetElementpointer;
GpisetElementpointerAtLabel;
GpioffsetElementpointer; and
GpiQueryElementpointer.
Whether a new element is inserted, or replaces an existing element, is determined
by the PS edit mode, which can be set to either SEGEM_INSERT which is the
default, or SEGEM_REPLACE. The PS edit mode is set and queried using:
ORDERS, ELEMENTS, AND SEGMENTS 1&J

GpisetEditMode; and
GpiQueryEditMode.
Functions also exist to delete the element at the cuITent element pointer, all the
elements in a given range (including the first and last in the range), and all the
elements between two labels (excluding the labels). These are performed using:
GpiDeleteElement;
GpiDeleteElementRange; and
GpiDeleteElementsBetweenLabels.
The element type and description string can be queried for the element at the
current element pointer position using:
GpiQueryElementType
Note that a segment with segment id of zero cannot be edited.
An example of segment editing is illustrated by the function Editsegment in
Figure 9-4. This opens a segment, replaces the first element, sets the element
pointer to a label, and inserts two new elements.

WHOLE SEGMENT EDITING FUHCTIOHS

In addition to the functions for editing the contents of individual segments and for
modifying segment attributes, a number of whole segment editing functions exist,
some of which have been mentioned earlier. Segments are created, reopened and
closed using:
Gpiopensegment; and
Gpiclosesegment.
Segment priority is set and queried using:
Gpisets egmentpriority; and
GpiQuerysegmentl}riority.
The identity of all existing segments in a given range can be queried using:
GpiQuerysegmentNames
Individual segments or a range of segments can be deleted using:
GpiDeletesegment; and
GpiDeletesegments.
188 OS/2 PRESENTATION MANAGER GPI

edl.tsegm.c */
L Edi.tsegment(HPS hps, LONG Isegld)

Set drawl.ng mode to DM_RETAIN, reopen the specl.fl.ed segment, edi.t l.t as */
descrl.bed below and draw the chai.n. */
It i.s assumed that the PS drawl.ng mode may not be DM_RETAIN on entry. */
*/
segment 1.s edl.ted as follows: */
ace the fi.rst element wi.th a Set Current Posi.tl.on (OCODE_GCSP) element.*/
the element poi.nter to label wl.th value 6. */
rt a Set Current Posi.tl.on (OCODE_GSCP) element. */
rt a Li.ne at Current Posl.ti.on (OCODE_GCLINE) element */
*/
*/
puts: hps Ps handle
lsegld Segment ID */
*/

#defl.ne LBL6 6L

B00L fRet /* B00L return code */


B00L fRets = FALSE /* B00L return code */
P0INTL ptlpoi.nt /* coordi.nate poi.nt */

/* set drawl.ng mode to retal.n */


fRet = Gpl.SetDrawl.ngMode( hps /* -PS handle */
DM_RETAIN /* -mode = retai.n */
in

l'f (fRet) /* reopen segment */


fRet = fRets = Gpl.Opensegment( hps /* -PS handle */
lsegld /* -segment i.d */
in

l.f (fRet) /* set element poi.nter to 1 */


fRet = Gpi.SetElementpoi.nter( hps /* -PS handle */
1L /* -element number */
in

l'f (fRet) /* set edl.t mode to replace */


fRet = Gpi.SetEdi.tMode( hps /* -PS handle */
SEGEM_REPLACE /* -mode = replace */
in

Pol.nt.x -300L;
Pol'nt.y -300L;
/* replace element by OCODE_GSCP
fRet = Gpi.Setcurrentposi.ti.on( hps /* -PS handle
&ptlpoi.nt /* -coordi.nate poi.nt
in

i.f (fRet) /* set element poi.nter at label */


fRet = Gpl.SetElementpol.nterAtLabel( hps /* -PS handle */
LBL6/* -label */
in

l'f (fRet) /* set edi.t mode to l.nsert */


fRet = Gpl.SetEdl.tMode( hps /* -PS handle */
SEGEM_INSERT /* -mode = l.nsert */
):

Figure 9.4 Editsegment Function.


ORDERS, ELEMENTS, AND SEGMENTS 189

Poi.nt.x = 200L:
Pol'nt.y -200L;
/* 1.nsert OCODE_GSCP element
fRet = Gpi.Setcurrentposl.tl.on( hps /* -PS handle
&ptlpoi.nt /* -coordi.nate poi.nt
in

Pol'nt.x -OL;
PO,.nt.y -100L;
/* i.nsert OCODE_GCLINE element */
fRet =(B00L)Gpl.L1.ne( hps /* -PS handle */
&ptlpol'nt /* -coordi.nate pol.nt */
in

1.f (fRets) /* close segment */


fRet = Gpi.Closesegment(hps) && fRet;

l'f (fRet) /* draw chai.n */


fRet = Gpl.Drawchal.n(hps);

return ( fRet ) ;

Figure 9.4 (co7i£Znzted)


Correlation and Boundary Data Accumulation

CORRELATION

The correlation functions enable an application to define a rectangle, called the


pick aperture, against which all drawing primitives Out not GpiErase) are com-
pared for intersection. Their purpose is to enable an application, such as a graphics
editor, to determine the primitive (or primitive group) a user has selected on the
display screen by pointing and clicking (e.g., using a mouse and pointer).
The pick aperture is defined in device independent coordinates in the PS Page.
If a non-retained drawing primitive intersects the pick aperture then a hit
(GPI_HITS) is returned for that primitive. For a non-retained primitive that does
not intersect the pick aperture, no hit (GPI_OK) is returned.
CoITelation is also supported for retained graphics that provides special func-
tions for performing correlation and identifying the location of any hits (i.e.,
position in segment, segment name, and segment call context).
The pick aperture size, for both retained and non-retained correlation, is set and
queried using:
GpisetpickAperturesize; and
GpiQuerypickAperturesize.

Hen-Retained Correlation

Non-retained correlation is enabled and disabled using:


GpisetDrawcontrol(hps, DCTL_CORRELATE,
DCTL_ONrocTL_OFF)

190
CORRELATION AND BOUNDARY DATA ACCUMULATION 191

and the pick aperture position is set and queried using:


GpisetHckAperdureposition; and
GpiQuerypickApertureposition.
With the DCTL_CORRELATT} draw control set, an individual drawing primitive
(e.g., GpiLine), GpiputData, GpiElement, or GpiplayMetaFile will return
GPI_HITS or GPI_OK, depending on whether or not the output from the operation
intersects the pick aperture, or GPI_ERROR if an error is detected. GpiErase will
never return a correlate hit.
Where the primitive is an area fill operation (e.g., GpiFullArqDRO_FILL or
GpiEndArea), a hit will be returned if the pick aperture lies partially or totally
within the filled area. If the primitive is an unfilled figure (e.g.,
GpiFullArqoRO_OUTLINE), a hit will be returned only if the pick aperture
intersects the figure boundary. Note that an area fill can return a coITelate hit even
if the AREABUNDLE pattern is set to no shading (i.e., PATSYM NONSIIADE), a
line can return a hit even with line-type set to LINETYPE_INVI-SIBLE, and a hit
can still be returned using mix values of FMLEAVEALONE or
BM LEAVEALONE.

Retained Correlation
Special puxpose functions exist to perfo]rm correlation on retained graphics seg-
ments. These specify the pick aperture position and the target segment or seg-
ments as parameters to the correlate request. The target can be an individual
segment, part of the segment ®icture) chain, or the complete chain.
In addition, where multiple hits are returned from a single retained correlation
operation, the segment tag attribute can be used by the application to distinguish
between the different hits.
Retained correlation is performed by processing the target segments exactly as
if they were being drawn, but performing correlation rather than drawing. Re-
tained coITelation is performed using:
Gpicorrelatechain;
GpicorrelateFrom; and
GpicoITelatesegment.
GpicorTelatechain performs correlation on the entire segment chain.
GpicorrelateFrom performs correlation starting from a specified segment and
stopping at a different specified segment. If the `stop' segment is not found during
the correlate operation, it is not an error, correlation continues to, and stops at, the
end of the chain. GpicoITelatesegment performs correlation on a single specified
segment.
Any retained correlation operation will also include all segments called directly
or indirectly from the specified segments, provided the segment attribute and tag
order values are set to enable correlation.
192 OS/2 PRESENTATION MANAGER GPI

The segment tag attribute associates a numerical tag value (or pick identifier)
with subsequent primitives in a retained segment for the puxpose of retained
correlation. GpisetTag will cause a Set (or Push and Set) Pick Identifier element
to be stored in the open segment at the cuITent element pointer position. When a
retained correlate hit is returmed, the tag attribute value at the hit location is
returned with the segment name to the application (see Figure 10-1). This enables
an application to determine the position of the hit and to distinguish between
different hits within the same segment. Multiple hits in the same segment with
the same tag value are registered as a single hit. When the segment is drawn, the
tag elements produce no output to the device.
If the tag value is zero (the initial default) or a segm.ent has a zero segment
identifier, correlation is disabled. Correlation is also enabled or disabled by the

:,i'jl;:,i! .:I;i l,:!; iIJ:,1


segment attributes. For correlation to be enabled, either the ATI`R DETECT-
ABLE segment attribute must be set or, if called from a detectable segment, the
value of the ATrR_PROP_DETECTABIE segment attribute must be set for the
calling segment. Correlation is not enabled for dynamic segments unless they are
unchained and are therefore being drawn non-dynamically. The application can
also specify whether correlation is required for only visible segments (i.e., those
with their ATI`R_VISIBIE segment attribute set), or for all segments as a param-
eter to the correlation functions.

GplsatTag(hp8 , 0) >

Gpls®tTag(hpB , 4) >

GplsetTag(hp8, 2) >

tA segment with ld I 0 will not r®tum corr.late bits.

Figure 10.1 Retained Segment CoITelation.


CORRELATION AND BOUNDARY DATA ACCUMULATION 193

Asacalledsegmentmaybecalledmultipletimes,itmustbepossibletodeterm.ine
the calling context of any hit. The coITelate information is returned, last hit first, in
an array of `segment identifier -primitive tag' pairs. The application specifies both
the maximum number of hits 04ax Hits) and the maximum number of id/tag pairs
to be returned for each hit (MaxDepth). The retained coITelation functions also
provide the number of hits returned identifying the size of the returned array.
Unused icy/tag pairs in the array are set to zero. The following are examples of
returned correlate information for different values of MaxHits and MaxDepth.
MaxHits = 1 MaxDepth = 1

OxOOll Segment ID IAST HIT


0xOOO8 Tag

MaxHits = 2 MaxDepth =4

OxOOll Segment id = 17 (called segment) IAST HIT

OxOOO8 Tag =8

Ox0013 Segment ID = 19 (root segment)

0x0006 Tag =6

OxOOOO unus ed

OxOOOO unused

OxOOOO unused

OxOOOO unus e d

OxOO19 Segment id = 25 (called segment)


NEXT TO IAST HIT
Ox000 5 Tag =5

Ox0017 Segment id = 23 (called segment)

Ox0004 Tag =4

Ox0013 Segment id = 19 (called segment)

Ox000 3 Tag =3

Ox0020 Segment id = 32 (called or root segment)

Ox0002 Tag =2
194 0S/2 PRESENTATION MANAGER GPI

BOUNDARY ACCUMULATION

Boundary accumulation enables the bounding rectangle of all drawing (excluding


GpiErase) to be accumulated and returned in model space. The bounding rectangle
is useful for `scale to fit' sub-picturing operations (see chapter 11), and for perform.-
ing optimizations and avoiding coordinate overdow (see chapter 7). Boundary
accumulation is enabled and disabled using:
GpisetDrawcontrol thps, DCTL_BOUNDARY,
DCTL_ONrocTL_OFF)
and the boundary rectangle is queried and reset using:
GpiQueryBoundaryData; and
GpiResetBoundaryData.
The rectangle returned from GpiQueryBoundaryData is inclusive at all bound-
aries (i.e., all rectangle coordinates are inside the rectangle) and the reset value,
or null boundary rectangle, has a negative width and height.
i.e., xLeft = Ox07FFFFFF
yBottom = Ox07FFFFFF
xRight = OxF8000000
yTop = OxF8000000
Boundary data is, of course, also reset by GpiResetps, Gpisetps, and
GpiplayMetaFile with the appropriate reset options.
MetaFiles

The MetaFile functions enable Gpi graphics pictures to be transferred between a


I}resentation Space and a MetaFile, allowing picture interchange between users
and applications. One application that exploits the MetaFile interchange capabil-
ities is the OS4 Clipboard.
A MetaFile represents a `snapshot' GPI graphics picture rather than an ani-
mated sequence. MetaFiles may be stored as disk files, as data in application
memory, or by the system as memory MetaFiles.

THE METAFILE FUNOTI0MS

A MetaFile is initially created by issuing GPI calls to a PS associated with a DC


of type OD_METAFILE or OD_METAFILE_NOQUERY. This records (or accurnu-
lates) the picture in memory. When DevcloseDC is issued to close the MetaFile
DC, the MetaFile is detached from the PS, and established as a memory MetaFile.
DevcloseDC returns the handle of the newly created memory MetaFile to the
application. A memory MetaFile can be saved to disk and deleted using
GpisaveMetaFile, or deleted without saving using GpiDeleteMetaFile. MetaFile
creation, as described above, is illustrated by the function RecordMetafile in
Figure 11-1, which also illustrates the use of GpisaveMetaFile to save the memory
MetaFile to disk.
If a MetaFile has previously been saved as a disk file, it can be loaded from disk
to re-create a new memory MetaFile using GpiLoadMetaFile.
If a MetaFile has previously been saved as data in application memory, it can be
used to re-create a new Memory MetaFile by opening and closing a MetaFile DC
and using GpisetMetaFileBits to transfer the data to this new MetaFile. This is
illustrated by the function CreateMetaFile in Figure 11-2. Note that when using
GpisetMetaFileBits, it is not necessary, to transfer all the data in a single

195
196 0S/2 PRESENTATION MANAGER GPI

operation. The offset and length parameters enable it to be issued multiple times
to transfer the data in blocks, one buffer at a time.
To transfer data from a MetaFile to application memory, GpiQueryMetaFile
Length can be used to determine the size of the MetaFile and, having allocated
sufficient memory, GpiQueryMetaFileBits can be used to transfer the data. Like
GpisetMetaFileBits, the offset and length parameters enable this function to be
issued multiple times to transfer the data in blocks, one buffer at a time.
A memory MetaFile may be drawn to a PS using GpiplayMetaFile described
below.

GPIPLAYMETAFILE

A MetaFile can be displayed as a normal non-retained picture by playing it to a PS


in DM_DRAW mode, or it can be transfeITed to retained segment store using
DM RETAIN or DM DRAWANDRETAIN mode. It can also be recorded in another
Met-aFile by playing it to a PS associated with a MetaFile DC.
An aITay of options is available for use with GpiplayMetaFile. Most of these
control whether the resource and environment inform.ation in the MetaFile is
ignored or is used to modify the presentation space. The main exceptions to this
are the PMF_RESET and PMF_SUPPRESS options.
GpiplayMetaFile, with the combination of options that most accurately re-cre-
ates the original MetaFile picture (with a non-realizable color table), is illustrated
by the function PlayMetaFile in Figure 11-3. The GpiplayMetaFile options are as
follows:

PMF SEGBASE

This is cumently reserved and should be specified as zero.

PMF LOADTYPE

This may be specified as one of the following:


LT_DEFAUIIT (i.e., LT_NOMODIFY) causes the viewing
transform. matrix values in the MetaFile segments to be ignored
and the value in the PS to be preserved and used for each
graphics segment opened during GpiplayMetaFile. It also
causes any graphics field definitions in the MetaFile to be
ignored.
LT_ORIGINALVIEW causes the viewing transfo]rm. matrix
values in the MetaFile segments to be used for the correspond-
ing graphics segments opened during by GpiplayMetaFile.
With this option, the graphics field definition in the MetaFile is
used to update the graphics field in the PS.
M ETAFI LES lgJ

PMF RESOLVE

This is currently reserved and should be specified as zero.

PMF LCIDS

This may be specified as one of the following:


LC_DEFAUIIT (i.e., LC_NOLOAD) causes the logical font
and bitmap id (or lcid) pattern resources defined in the MetaFile
to be ignored and those in the PS to be preserved and used for
displaying the MetaFile picture. This option is applicable if the
required fonts and bitmap patterns are already available in the
PS.
LC_LOADDISC causes the logical font and bitmap id (or lcid)
pattern resources defined in the MetaFile to be loaded into the
PS, replacing any existing PS set ids with the same value, and
used for displaying the MetaFile picture.

PMF RESET

This may be specified as one of the following:


RES_DEFAUIIT (i.e., RES_NORESET) plays the MetaFile
normally without performing a reset.
RES_RESET causes the page units, page size, device trans-
form, and default viewing transfo]rm to be set to the values
defined in the MetaFile, and the PS to be reset with the equiv-
alent of a GpiResetps (GRES_ALL) function. This option is
equivalent to creating a new PS with page units, page size, and
default viewing transfo]rm. identical to those defined in the
MetaFile. This function is useful because it is not possible to
determine the MetaFile page units, and so forth, in advance of
GpiplayMetaFile in order to specify these values on
Gpicreateps.

PMF SUPPRESS

This may be specified as one of the following:


SUP_DEFAUIIT (i.e., SUP_NOSUPPRESS) plays the MetaF-
ile normally without suppressing drawing.
SUP_SUPPRESS is intended for use with the RES RESET
option. These two options together enable the PS to be reset as
described for RES_RESET without processing the remainder of
the MetaFile resources or performing any drawing. The appli-
198 OS/2 PRESENTATION MANAGER GPI

cation may then modify the PS environment and resources as


required (e.g., by issuing GpisetDefaultviewMatrix to scale the
picture or Gpicreatel.ogcolorTable to load the color table) and
then play the MetaFile a second time without the RES RESET
and SUP_SUPPRESS options. This then displays the rietaFile
using the modified environment and resources. This is
illustrated by the function PlayMetaFile_Modify in Figure 11-4.
This particular example reverses the PS background and fore-
ground colors to display the MetaFile with a black background.
This might be used for displaying a MetaFile converted from a
PIF file for example.

PMF COLORTABLES

This may be specified as one of the following:


CTAB_DEFAULT (i.e., CTAB_NOMODIFY) causes the logi-
cal color table defined in the MetaFile to be ignored and the
color table in the PS to be preserved and used for displaying the
MetaFile.
CTAB_REPIIACE causes the logical color table defined in the
MetaFile to be loaded, replacing the existing color table in the
PS. The PS color table is not reset by this option and existing
PS color table entries not defined by the MetaFile are unmodi-
fied. This option therefore enables an application to use the
MetaFile to append to an existing application defined color
table and then use this modified color table for displaying the
MetaFile picture.

PMF COLOREALIZABLE

This may be specified as one of the following:


CREA_DEFAULT (i.e. , CREA_NOREALIZE) causes the color
table defined in the MetaFile to be loaded into the PS without
its realize option set. This is the normal value of this option.
Most MetaFiles do not contain realizable color tables.
CREA_REALIZE is a no-op and should not be used.
CREA_DOREALIZE (3L) was added by a 1.2 CoITective Ser-
vice Diskette (and included in 1.3) together with support for
GpiRealizecolorTable and gray scale changes in the display
driver for the 8514/A display adapter. This will load the color
table defined in the MetaFile as a realizable color table and
realize it (effectively performing GpiRealizecolorTable) before
playing the remainder of the MetaFile. It is the responsibility
M ETAFI LEs lee

of the application to subsequently issue GpiunrealizecolorT-


able at the appropriate time. Note that the CRE DOREALIZE
constant is not defined in the 1.2 header files.

PMF DEFAunTs

This may be specified as one of the following:


DDEF_DEFAIJIJr (i.e., DDEF_IGNORE) causes default at-
tributes defined in the MetaFile to be ignored and those in the
PS to be preserved and used for displaying the MetaFile picture.

DDEF LOADDISC causes default attributes defined in the


MetaFile-tobesetinthePS,replacingexistingdefaultattribute
settings.

METAFILE PRIMTIHG AHD METAFILE T0 METAF.LE RE00RDIHG

As explained above, the SUP_SUPPRESS option is useful for allowing application


intervention between PS initialization and playing the remainder of the MetaFile.
If, however, the RES_RESET option is required when playing a MetaFile to a PS
associated with an OD_QUEUEDflM_Q_STD printer or MetaFile DC, use of the
SUP_SUPPRESS option is essential @ES_RESET might be required, for exam-
plc, to ensure that the MetaFile is printed or recorded with its original PS page
units and size). Any attempt to issue GpiplayMetaFile with RES RESET after
GpiAssociatewiththeseDCtypes,isintexpretedasanattempttoch-angethepage
units, which is invalid. An error will be returned and a PMERR NO METAF-
ILE_IIANDLE or PMERR_INCOMPATIBLE_METAFIRE eITor will be logged. If
the RES_RESET and SUP_SUPPRESS options are used, they must, therefore, be
issued before GpiAssociate. This is illustrated by the function nrintMetaFile in
Figure 11-5. This restriction applies only if the target is a MetaFile DC or an
OD_QUEUED DC with data type PM_Q_STD.

SOALING A METAFILE To Flir AM output AREA

A common requirement is to scale a MetaFile to fit an output area. This is


accomplished by playing the MetaFile initially without displaying it to accumulate
the boundary data, and then using the boundary data to define the required
transform. This is illustrated by the function ScaleMetaFile in Figure 11-6, which
scales the MetaFile to fit any specified rectangle (although typically the full screen
or fo]rm size) in the PS page.
ZOO 0S/2 PRESENTATION MANAGER GPI

DISPLAYING A METAFILE AS A SUB-PICTURE

Another common requirement is that of displaying a MetaFile as a sub-picture of


an existing picture. This is illustrated by the function SubpictureMetaFile in
Figure 11-7, which is very similar to the function ScaleMetafile. The MetaFile is
first played without displaying it to accumulate boundary data and the boundary
data is then used to determine the required transform. matrix. As this transfo]rm.
will vary during drawing of the combined picture, a picture rather than a PS
environment attribute should be used. The viewing transformi matrix is therefore
used in place of the default viewing transfo]rm. used above by ScaleMetafile. The
advantage of this is that it enables the combined picture and sub-picture to be
recorded in a new MetaFile, if required, without violating the MetaFile inter-
change architecture.
Note that SubpictureMetaFile enables the default viewing transfo]rm. to be used
for scrolling and scaling the original picture without affecting the position and size
of the sub-picture. If it is a requirement to scroll and scale the sub-picture together
with the original picture (using the default viewing transform) then this is easily
accomplished by removing the Gpiconvert function, effectively causing the target
rectangle to be defined in default page coordinates rather than page coordinates.
Unfortunately, the function SubpictureMetaFile as illustrated does not cur-
rently work correctly with IBM OSA version 1.2. Out this is coITected by 1.3). On
1.2 it is necessary to replace GpisetviewingThansformMatrix (I'RANSFORM_RE-
PIACE) by GpisetDefaultviewMatrix ITRANSFORM_PREEMPI). This will ac-
tually work for all versions but is not ideal for the reasons explained above.

METAFILE RESTRICTIONS AND ESCAPE ORDERS

The intermal format of a MetaFile provides a definition of the environment and


resources, followed by the graphics segments containing orders defining the
picture content (see the IBM Graphics Architecture Reference, Document Refer-
ence, and OS# nrogramming Reference manuals).
This `snapshot' representation of the graphics picture is not ideally suited to
handling changes in environment and resources that occur during picture draw-
ing, hence the distinction between PS environment/resources and picture func-
tions discussed in chapter 1. As a consequence of this, certain rules exist for the
creation of valid (i.e., SAA conforming) MetaFiles. When recording a MetaFile,
some invalid functions will affect the integrity of the MetaFile picture, some will
return an error, some wi.Il be ignored, and some will be recorded as MetaFile
escape orders. A MetaFile escape order is not the same as a recorded DevEscape
function, although the latter is one of a number of functions that can be recorded
in a MetaFile escape order. MetaFiles containing MetaFile escape orders will
generally interchange successfully with other OSA Hesentation Manager sys-
terns but attempts to interchange them with other products that conform to the
same (SAA) interchange architecture may fail because the MetaFile escape orders
will not be recognized.
M ETAFI LES T01

In general, any change to the PS environment or resources after the start of the
picture will be recorded as a MetaFile escape order. The picture staid occurs when
the first Gpiopensegment, drawing primitive, or primitive attribute function is
issued.
The rules for creating a valid MetaFile are as follows:

1. Page units and dimensions appear only once in a MetaFile and may
not be altered after the first association of a PS and MetaFile DC. Any
attempt to issue Gpisetps or GpiAssociate to associate the MetaFile
DC with a PS with different page units and/or size after the picture
start will return an error. The page units and size stored in the
MetaFile are specified for the PS either at creation tine or the last
Gpisetps (or GpiplayMetaFile with option RES_RESET) prior to
association with the MetaFile DC. Any modifications to page units/de-
vice transformi made using Gpisetpageviewport are ignored for the
purpose of MetaFile creation, even if performed before association
with the MetaFile DC.
Note that use of GpiAssociate to disassociate the MetaFile DC from its
PS and associate it with another PS is valid so long as the PS page
units and size of the new PS are identical to those already recorded in
the MetaFile.
2. Default viewing transfo]rm forms part of the MetaFile environment
information and should therefore be established before any drawing
occurs. If issued after the picture start GpisetDefaultviewMatrix will
be recorded as a MetaFile escape order.
3. WinDrawTezit and similar WinDraw functions are intended only for
output to display devices in non-retained mode. Such calls directed at
a PS associated with a MetaFile DC will be ignored and not recorded
in the MetaFile.
4. GpiBitBlt, Gpisetpel, and GpipaintRegion are intended for non-re-
tained use only. These functions, if issued during MetaFile recording,
are recorded as MetaFile escape orders. Note that GpiwcBitBlt is
supported by the MetaFile architecture and may be used for BitBlt
operations without producing MetaFile escape orders.
5. A valid MetaFile has no means of recording the graphics field. Graph-
ics field should therefore be set to no clipping (i.e., the default) for the
duration of MetaFile recording, otherwise GpisetGraphicsField will
be recorded as a MetaFile escape order.
6. Color tables form part of the MetaFile resources and should therefore
be established before any drawing occurs. If issued after the picture
start, Gpicreatel.ogcolorTable will be recorded as a MetaFile escape
order.
7. Default attributes form part of the MetaFile environment information
and should therefore be established before any drawing occurs. If
issued after the picture start, any of the following functions will be
recorded as MetaFile escape orders:
202 OS/2 PRESENTATION MANAGER GPI

GpisetDefAttrs;
GpisetDefviewingLimits;
GpisetDeITag; and
GpisetDefArcparans.
8. Avalid MetaFile has no means of recording the clip region. Clip region
should therefore be set to no clipping (i.e., the default) for the duration
of MetaFile recording, otherwise any of the following functions will be
recorded as MetaFile escape orders:
GpisetclipRegion;
GpiExcludeclipRectangle;
GpilntersectclipRectangle; and
GpioffsetclipRegion.
9. The draw control DCTL DISPLAY must be set (to DCTL_ONI for the
duration of MetaFile -recording. If the draw control is set to
DCTL_OFF during any drawing, or if GpisetDrawcontrol is used to
modify the DCTL_DISPLAY draw control after drawing has started,
this is recorded as a MetaFile escape order.
10. Logical font and bitmap ids form part of the MetaFile resources. These
are defined using GpicreateLogFont and GpisetBitmapld either be-
fore any drawing occurs or incrementally during drawing as they they
are required. GpiDeletesetld must not, however, be used to delete any
ids until after the PS and DC are disassociated, or, in the case of a
Micro-PS, should not be used at all (i.e., the system should be left to
delete the set ids when the PS and DC are destroyed). Any of these
functions, when used in an incorrect manner, are recorded as MetaFile
escape orders.
11. Bitmaps are used both as area fill patterns and as the source ofBitBlt
operations and therefore fo]rm part of the MetaFile resources. These
should be loaded (or created) before any drawing occurs or may be
added incrementally during drawing as they are required.
GpiDeleteBitmap should not, however, be used to delete any bitmap
before all required bitmaps have been created and bitmaps must not
be modified during drawing. If bitmaps are deleted prematurely or
modified during drawing, then incorrect data may be recorded in the
MetaFile.
12. None of the following functions should be issued. If issued, they will be
recorded as MetaFile escape orders.
GpiErase;
GpiResetps;
Gpisetcp;
M ETAFI LES TOO

Gpisaveps; and

GpiRIstoreps.
13. DevEscape calls with system escape codes in the range 8150-24449
and non-system escape codes in the range 40960-57343 are recorded
as MetaFile escape orders (note that for PM_Q_STD print files, the
corresponding ranges are 16300-32599 and 49152-65535 respectively).
Other DevEscapes may be passed to the display driver or ignored,
depending on the value of the individual escape code.
14. Only a limited range of foreground and background mix values should
be used. These are:

FM_DEFAULT,

FM_OR;

FM_OVERPAINI;

FM_LEAVEALONE;

BM_DEFAULT;

BM_OVERIIAINT; and

BM LEAVEALONE.
Other mix values will be recorded and will interchange successfully
with other OSA systems but may not be understood if interchanged
with other products conforming to the same interchange architecture.
15. Match numbers (i.e., the lMatch field in the FATI`RS structure) should
not be used for font creation when recording a MetaFile. Match
numbers are not recorded in the MetaFile.
16. Duplicate segment ids (other than zero) are invalid in a MetaFile.
GpiDrawchain, GpiDrawFrom, and GpiDrawsegment should not be
used to draw the same retained root segments more than once when
recording a MetaFile. Likewise, Gpiopensegment should not be used
to open a new non-retained segment with a previously used non-zero
segment id. A MetaFile containing segments with duplicate ids (other
than zero) may return an error when subsequently played.
17. Care must be taken when creating MetaFiles on one device for inter-
change with another. For example, whereas an 8514/A display driver
can support a color table (and color attributes) with up to 256 indices,
most other drivers can support only 64 (as returned by the
DevQuerycaps CAPS_COLOR_INDEX element). Exploiting the full
color capabilities of the 8514/A driver will therefore produce a MetaF-
ile that will not interchange successfully with a system using a VGA
for example.
204. OS/2 PRESENTATION MANAGER GPI

PIE FILES AHD PICTURE FUHCTIOH CALLS

The PIF, or Picture Interchange File format, is an earlier IBM interchange format
that existed before the MetaFile architecture was established. PIF format resem-
bles that of a MetaFile and the Picture Utilities ®icichg, picshow, and picprint)
enable an end user to convert files from PIF to MetaFile format, and to display and
print both PIF files and MetaFiles. In addition, the Hcture function calls Piclchg
and Picprint allow equivalent PIF to MetaFile conversion and printing operations
to be accessed as application function calls.
Picnrint includes a parameter string, equivalent to the print queue processor
parameters on DevopenDC. Although PicFTint provides a simpler method of
printing a MetaFile than that described earlier using GpiplayMetaFile, it lacks
the flexibility provided by the GpiplayMetaFile options. Note that Piclchg also
provides the capability of converting symbol sets to fonts. Symbol sets resemble
fonts but represent an earlier character set architecture (used by PIF files and
other products).

recmeta.c */
OL RecordMetaFi.le (HAB hab, HPS hps, PSZ pszFi.lename )

Record a MetaFl.1e and save 1.t to di.sk. The i.nput PS must not be associated
wl.th a DC.

I.nputs: hab anchor block handle


hps PS handle
pszFi 1 ename fl.le name for new MetaFl.1e

"Have a ni.ce day!..


#define METAFILETEXT
#defl.ne METAFILETEXTLEN (LONG)(si.zeof(METAFILETEXT))

HDC hdc : /* DC handle


HMF hmf = DEV_ERROR ; /* MetaFi.le handle
B00L fRet = FALSE ; /* B00L return code
P0INTL ptl poi.nt /* coordi.nate poi.nt
DEVOPENSTRUC dopData /* DEVOPENSTRUC structure
statl.c MATRIXLF matlf { Ox20000, OL, OL, OL, Ox20000, OL, 20L, 20L,1L }

/* set DevopenDC params


dopData . psz LogAdd ress NULL; /* -logi.cal address
"DISPLAY"
d o p D a t a . p s z D r 1. v e r N a in e /* -dri.ver name
d o p D a t a . p d r i. v NULL; /* -DRIVDATA
dopData . pszDataType NULL: /* -data type
dopData . pszcomment NULL; /* -comment
dopData . pszoueueprocName NULL; /* -queue proc name (default)
dopData . pszQueueprocpa rams NULL; /* -queue proc params
dopData . pszSpool erpa rams NULL; /* -spooler params
dopData . pszNetworkpa rams NULL: /* -network params (not used)

Figure 11.1 RecordMetaFile Function.


METAFILES

/* open a MetaFi.le DC
hdc = DevopenDC( hab /* -anchor block handle
OD_METAFILE /* -DC type
I * ,,
/* -token
9L /* -number of data elements
(PDEVOPENDATA)&dopData /* -open DC data
NULL /* -compati.ble hdc (N/A)
);

/,*,***************************************************************************1
/* */

): ::i!s:::?:::e:.:n:pT::::!e;: :::ira;T::Zs!g:eo::..::Tei:.::e]gg;:::r :)
/* color tables,1ogl.cal fonts, bl.tmaps, default attrl.butes, default vi.ew */

): 8:i|::o:T:t:: Page unl.ts). Note that GP1.Setps may not be I.ssued after :)
/* */
/****************************************************************************'1

I.f#::!=D::T§:3::}auitvi.ewMatri.x; !Es (: :::ir::;:::C:i :::uT:::fy rs

&matlf
TRANSFORM_REPLACE
n
1` f ( f R e t ) /* assocl.ate PS and DC
fRet = Gpi.Associ.ate( hps /* -PS handle
hdc /* -DC handle
in

ptlpoi.nt.x = 100L;
ptlpo,.nt.y -100L;
l`f (fRet) /* draw to MetaFi.1e */
fRet = (B00L)Gpl.Charstrl.ngAt( hps
' &ptlpol'nt
M ETA F I L ET EXT L EN
METAFI LETEXT

l'f (fRet) ate PS and DC


fRet = Gpi.Assocl.ate( hps ndle
NULL DC handle (NULL)
in
I,*+**************************************************************************1
/*
i
*/
/: Destroy ps resources here. */
/* */
/****************************************************************************'/

1.f (hdc!=DEV_ERROR)
hmf = DevcloseDC(hdc); /* close the DC */
1.f (hmf !=DEV_ERROR && fRet) /* save MetaF1.1e to dl.sk */
fRet = Gpl.SaveMetaFi.1e( hmf /* -MetaF1.1e handle */
pszFi.lename /* -fi.le name */
n
else
fRet = FALSE:

retu rn ( f Ret ) ;

Figure 11.1 (con££nwecz)


206 OS/2 PRESENTATION MANAGER GPI

crtmeta.c */
CreateMetaFl.1e(HAB hab, LONG IDataLength, PBYTE pbMetaFi.leData)

Create a MetaFi.le and I.ni.ti.all.ze 1.t from appli.cation memory.

I.nputs: ]3:taLength i::::: ::°S:t::Ti:edata (app|i.cati.on buffer)

pbMetaFi.1eData poi.nter to MetaFi.le data (appll.cati.on buffer)

returns: HMF MetaFi.1e handle or DEV_ERROR

HDC hdc /* DC handle


B00L fRet = FALSE /* B00L return code
DEVOPENSTRUC dopData /* DEVOPENSTRUC structure
HMF hmf = DEV_ERROR /* MetaFl.1e handle

/* set DevopenDC data


/* -logi.cal address
#::::i:z::?:::I::: : #;LAY„; /* -dri.ver name
/* -DRIVDATA

#:::::i::i:taType : W::; /* -data type


dopData.pszcomment = NULL: /* -comment
dopData.pszQueueprocName = NULL: /* -queue proc name (default)
dopData.pszoueueprocparams = NULL; /* -queue proc params
dopData.pszSpoolerparams = NULL; /* -spooler params
dopData.pszNetworkparams = NULL; /* -network params (not used)

/* open a MetaFi.le DC
hdc = DevopenDC( hab /* -anchor block handle
OD_METAFILE /* -DC type
* ,, /* -token
9L /* -number of data elements
(PDEVOPENDATA)&dopData /* -open DC data
NULL /* -compatible hdc (N/A)
in

I.f (hdc!=DEV_ERROR)
hmf = DevcloseDC(hdc); /* close MetaFi.le DC

if (hmf !=DEV_ERROR) /* set the MetaFi.le data


fRet = Gpl.SetMetaFi.leB1.ts( hmf /* MetaFi.1e handle
OL /* MetaFile Offset
lDataLength /* Length of data
pbMetaF1.leData /* MetaF1.1e data buffer
);

if (!fRet) /* delete i.f error


(
Gpi. Del eteMeta Fi 1 e ( hmf ) :
hmf = DEV_ERROR;
)
return ( hmf ) :

Figure 11.2 CreateMetaFile Function.


M ETAFI LEs Tor

playmeta.c */
OL PlayMetaF1.le(HPS hps, PSZ pszF1.1eName)

Play MetaFi.1e to the PS wl.th the combl.nati.on of opti.ons that most


accurately recreates the orl.gl.nal the orl.gl.nal MetaFl.le pl.cture.

1.nputs: hps PS handle


pszFi.leName fi.1e name of MetaFi.le

#defi.ne NOPTI0NS (LONG)(PMF_DEFAULTS+1)


#defl.ne LDESC 256L

B00L fRet = FALSE /* B00L return code


LONG Isegcount /* returned segment count
BYTE abDesc[LDESC] /* returned descrl.ptl.ve array
LONG al0pns[NOPTI0NS] /* Gpi.PlayMetaFl.1e opti.ons
HMF hmf = GPI ERROR /* MetaFi.1e handle
SIZEL si.zl /* PS sl'ze
ULONG ul0pti.ons /* PS page uni.ts

ge uni.ts and si.ze


uloptl.ons = Gpi.Oueryps( hps
&sl'zl
in

if (ulopti.ons!=GPI_ERROR) /* load the MetaFi.le


hmf = Gpl.LoadMetaFi.1e( hab /* -anchor block handle
pszFi.1eName /* -fi.le name
in
/* set play MetaFi.le options
a 1 0pn s [ PM F_S EGBAS E ] OL /* -reserved
a 1 0pn s [ PM F_LOADTY P E ] LT_ORIGINALVIEW;/* -transform opti.on
a 1 0pn s [ PM F_RESO LV E ] OL: /* -reserved
a l opn s [ PM F_LC I DS ] LC_LOADD I SC ; /* -1cl.d opti.on
a l opn s [ PM F_RES ET ] RES_RESET; /* -reset optl.on
a l opn s [ PM F_SU P P RESS ] SUP_NOSUPPRESS /* -suppress opti.on
a 1 0pn s [ PM F_CO LO RTAB L ES ] CTAB_RE P LAC E ; /* -color table opti.on
a 1 0pn s [ PM F_CO LO RREA L I ZAB LE ] C R EA_NO R EA L I Z E /* -color reali.ze optl.on
a l opn s [ PM F_DE FAU LTS ] DD E F_LOAD D I SC : /* -default attrl.bute opti.on

I.f (hmf !=GPI_ERROR) lay the MetaFi.1e */


fRet = (B00L)Gpi.PlayMetaFi.le( hps PS handle */
hmf MetaFi.le handle */
NOPTI0NS opti.on count */
alopns 0 p t 1' 0 n s */
&1Segcount ret seg count (reserved) */
LDESC sl.ze of descri.pti.ve array */
abDesc returned descri.ptl.ve array*/
n
1.f (hmf !=GPI_ERROR) /* delete the MetaFl.1e */
fRet = Gpi.DeleteMetaFi.le(hmf) && fRet:

l'f (fRet) /* restore PS page uni.ts


fRet = Gpi.Setps( hps /* PS handle
&sl'Zl /* PS sl'ze
ulopt,'ons /* PS page uni.ts etc.
n
return (fRet);

Figure 11.3 PlayMetaFile Function.


208 OS/2 PRESENTATION MANAGER GPI

/* playmetm.c */
B00L PlayMetaF1.1e_Modi.fy(HPS hps, PSZ pszFi.leName)

/* Play the MetaFile fi.rst wl.th the reset and suppress opti.ons to reset the
/* PS to the page uni.ts etc. defi.ned i.n the MetaFi.1e. Next modi.fy the PS
/* resources as requi.red then play the MetaFi.le a second ti.me wi.thout
/* speci.fyi.ng reset and suppress to dl.splay I.t.
/*
/* In the example gi.ven here, the PS color table l.s modi.fi.ed to change the
/* background color to black and the neutral foreground color to whi.te. The
/* PS i.s then erased to black before drawl.ng the MetaFl.1e. Thl.s parti.cular
/* example wi.ll work for normal MetaFi.1es recorded wi.th default background
/* and foreground color table values as the MetaFl.le wi.ll not defi.ne the
/* actual RGB values for these colors. MetaFi.les that do defl.ne these RGB
/* values wi.ll requi.re the CTAB_NOMODIFY opti.on to be speci.fi.ed on the
/* second and fi.nal Gpi.PlayMetaFi.1e (i..e. to use the default color table).
/*
/* 1.nputs: hps PS handle
/* pszFl.leName fl.le name of MetaFi.le
/*

#defi.ne NOPTI0NS (LONG)(PMF_DEFAULTS+1)


#defl.ne LDESC 256L
#defi.ne NALTABLE 4L

B00L fRet = FALSE ; /* B00L return code


LONG Isegcount : /* returned segment count
BYTE abDesc[LDESC] /* returned descri.pti.ve array
LONG alopns[NOPTI0NS] ; /* Gpl.PlayMetaFl.le optl.ons
HMF hmf . /* MetaFi.le handle
stati.c LONG alTable[NALTABLE] /* color table data
(OL /* l'ndex 0
OxOOOOOOOOL /* black
7L /* 1.ndex 7
OxOOFFFFFFL /* whl'te
);

/* load the MetaFi.1e


hmf = Gpi.LoadMetaFi.le( hab /* -anchor block handle
pszFi.leName /* -fl.1e name
);
/* set play MetaFl.le optl.ons:
/* for reset and suppress
a 1 0pn s [ PM F_S EGBAS E ] OL; /* -reserved
a 1 0pn s [ PM F_LOADTY P E ] LT_D E FAU LT : /* -transform opti.on
a l opn s [ PM F_RESO LV E] OL: /* -reserved
a l opn s [ PM F_LC I DS ] LC_D E FAU LT : /* -1ci.d opti.on
a l opn s [ PM F_RES ET] RES_RESET: /* -reset opti.on
a 1 0pn s [ PM F_SU P P RESS ] S U P_S U P P R ES S /* -suppress optl.on
a l o pn s [ PM F_CO LO RTAB L ES ] CTAB DEFAULT /* -color table optl.on
a l opn s [ PM F_CO LO RREA L I ZAB L E ] C REA_D E FAU LT /* -color reall.ze opti.on
a l opn s [ PM F_D E FAU LTS ] DDEF DEFAULT /* -default attri.bute optl.on
*/
I.f (hmf !=GPI_ERROR) play the MetaFi.1e
-PS handle */
fRet = (B00L)Gpi.PlayMetaFi.le( hps
hmf -MetaFi.le handle */
NOPTI0NS
-opti.on count */
alopns - 0 p t 1. 0 n S */
&1Segcount ret seg count (reserved) */
LDESC si.ze of descrl.pti.ve array */
abDesc returned descrl.pti.ve array*/
in

Figure 11.4 PlayMetaFile_Modify Function.


METAFILES 209

l'f (fRet) change PS resources */


fRet = Gpl.CreateLogcolorTable( -PS handle */
- 0 p t 1' 0 n S */
-format */
start i.ndex (N/A) */
number of alTable elements*/
i.ndex/RGBcolor table array*/

if (fRet) /* erase the wi.ndow


fRet = Gpi.Erase(hps): /* background to black

/* set play MetaFi.1e opti.ons:


/* no reset and normal play
a l opn s [ PM F_S EGBAS E ] OL; /* -reserved
a l opn s [ PM F_LOADTY P E ] LT_0 R I G I NA LV I EW /* -transform opti.on
a 1 0pn s [ PM F_RESO LV E ] 0L: /* -reserved
a l opn s [ PM F_LC I DS ] LC_LOADDI SC ; /* -lc,'d Optl'on
a l opn s [ PM F_RES ET] RES_NORES ET ; /* -reset opti.on
a l opns [ PM F_SU P P RESS ] S U P_NOS U P P R ES S : /* -suppress opti.on
a 1 0pn s [ PM F_CO LO RTAB LES ] CTAB_RE P LAC E ; /* -color table opti.on
a 1 0pn s [ PM F_CO LO RREA LI ZAB LE] C REA_NO REA L I Z E ; /* -color reall.ze optl.on
a l o pn s [ PM F_D E FAU LTS ] D D E F_LOAD D I S C : /* -default attri.bute optl.on

l'f (fRet) /* play the MetaF1.le */


fRet = (B00L)GpiplayMetaFi.1e( hps /* -PS handle */
.hmf /* -MetaFi.1e handle */
(LONG)NOPTI0NS/* -optl.on count */
al0pns /* -Optl'Ons */
&lsegcount /* -ret seg count (reserved) */
LDESC /* -si.ze of descri.pti.ve array */
abDesc /* -returned descrl.ptl.ve array*/
);

i.f (hmf !=GPI_ERROR) /* delete the MetaF1.le */


fRet = Gpl.DeleteMetaFi.le(hmf) && fRet:

return (fRet);

Figure 11.4 (Co7}fz7?ztecz)


210 OS/2 PRESENTATION MANAGER GPI

prl'ntmet.c */
L Pri.ntMetaFi.1e(HAB hab, HPS hps, HDC hdc, PSZ pszMetaFi.le)

Thi.s functi.on plays a MetaFl.le wl.th the RES_RESET optl.on to a PM_Q_STD,


OD_QUEUED pri.nter DC.

Play the MetaFi.1e to the PS wl.th RES_RESET and SUP_SUPPRESS optl.ons to


reset the PS to match the MetaFi.le. Associ.ate the PS and DC then play
MetaFi.1e without the reset and suppress optl.ons. Dl.ssocl.ate the PS
and return.

Note that the Reset opti.on must be used before Gpl.Assocl.ate to avoi.d a
PMERR_INCOMPATIBLE_METAFILE error. It 1.s assumed that the PS and DC are
not associ.ated on entry.

i.nputs: hab anchor block handle


hps PS handle
hdc DC handle
pszFl.1eName fl.1e name of MetaFl.le

#defi.ne PDOCNAME .`Pri.nt Job"


#defl.ne PDOCNAMELEN (LONG)si.zeof(PDOCNAME)
#defi.ne NOPTI0NS (LONG)(PMF_DEFAULTS+1)
#defi.ne NDESC 256L

B00L fRet = FALSE B00L return code


B00L fRetA = FALSE B00L return code
HMF hmf MetaFi.1e handle
USHORT usJobld returned job i.d
LONG Isegcount returned segment count
LONG abDesc[NDESC] returned descrl.pti.ve array
LONG alopns[NOPTI0NS] Gpi.PlayMetaFile options
LONG I Length 1 ength

load the MetaFile


hmf = Gpi.LoadMetaFi.le( hab -anchor block handle
-MetaFi.le fi.le name
pszMetaF1.le
n
set play MetaFi.le opti.ons
for reset and suppress
a l opn s [ PM F_S EGBAS E ] OL;
-reserved
a 1 0pn s [ PM F_LOADTY P E ] LT_D E FAU LT : -transform opti.on
a 1 0pn s [ PM F_RESO LV E ] OL;
-reserved
a l opn s [ PM F_LC I DS ] LC_D E FAU LT : -lcl'd Optl'On
a 1 0pn s [ PM F_RES ET ] RES_RES ET ; -reset opti.on
a l opn s [ PM F_SU P P RESS ] SUP SUPPRESS -suppress optl.on
a l opn s [ PM F_CO LO RTAB LES ] CTAE DEFAULT -color table opti.on
a l o pn s [ PM F_CO LO RREA L I ZAB L E ] CREA-DEFAULT -color reali.Ze optl.on
a 1 0pn s [ PM F_D E FAU LTS ] DDEF-DEFAULT -default attri.bute opti.on

play the MetaFi.le wl.th */


if (hmf !=GPI_ERROR) reset and suppress optl.ons */
fRet = (B00L)Gpl.PlayMetaFi.1e( hps -Ps handle */
hmf -MetaF1.le handle */
NOPTI0NS
-opti.on count */
al0pns -Optl'Ons */
&1Segcount -ret seg count (reserved) */
NDESC
-si.ze of descri.pti.ve array */
-returned descri.pti.ve array*/
. (PBYTE)abDesc
);

Figure 11.5 nrintMetaFile Function.


METAFILES 211

l'f (fRet) /* assocl.ate PS and DC


fRet = fRetA = Gpi.Assocl.ate(hps, hdc);

lLength -OL;
l'f (fRet) /* 1.ssue start doc DevEscape
fRet = DevEscape( hdc /* -DC handle
DEVESC_STARTDOC /* -escape code
PDOCNAMELEN /* -sl.ze of document name
PDOCNAME /* -null terml.nated doc name
&1Length /* -si.ze of output data (OL)
NULL /* -output data (not used
) --DEV_OK;

/* set play MetaFl.1e opti.ons:


/* no reset and normal play
a 1 0 pn s [ PM F_S EGBAS E ] OL; /* -reserved
a l opn s [ PM F_LOADTY P E ] LT_0 R I G I NA LV I EW /* -transform opti.on
a 1 0pn s [ PM F_RESO LV E ] 0L; /* -reserved
a l opns [ PMF_LC I DS ] LC_LOADDI SC : /* -1cl.d opti.on
a 1 0pns [ PMF_RES ET] R ES_NO RES ET ; /* -reset opti.on
a l opn s [ PM F_SU P P RESS ] SUP_NOSUPPRESS ; /* -suppress opti.on
a l opn s [ PM F_CO LO RTAB LES ] CTAB_RE P LAC E ; /* -color table opti.on
a l o pn s [ PM F_CO LO RR EA L I ZAB L E ] C REA_NO REA L I Z E ; /* -color reali.ze optl.on
a 1 0pn s [ PM F_D E FAU LTS ] DDE F_LOADD I SC : /* -default attri.bute option
1.f (fRet) /* play the MetaFi.le */
fRet = (B00L)Gpi.PlayMetaF1.le( hps */
/* -PS handle
.hmf /* -MetaFi.1e handle */
(LONG)NOPTI0NS/* -optl.on count */
alopns /* -Optl.ons */

#:§8Count ;: ::;:es:: :::::I.#;:r:::!y :;


(PBYTE)abDesc /* -returned descrl.pti.ve array*/
in
i.f (hmf !=GPI ERROR)
/* delete the MetaF1.1e */
fRet = Gpi.DeleteMetaFi.1e(hmf) && fRet;

lLength = 2L:
1' f ( f R e t )
l.ssue end doc DevEscape
fRet = DevEscape( hdc -DC handle
DEVESC_ENDDOC escape code
OL length of i.nput data
NULL i.nput data (not used)
&lLength si.ze of output data
(PBYTE)&usJobld output data (ret job
) --DEV_OK:

1' f ( f R e t A )
fRet = Gpi.Associ.ate(hps, NULL) && fRet; /* di.ssoci.ate PS and DC
*/
return ( fRet ) ;

Figure 11.5 (con£Z7}zteczJ


212 OS/2 PRESENTATION MANAGER GPI

/* scalemet.c */
B00L ScaleMetaFi.le(HPS hps, HMF hmf, PRECTL prclTarget)
(
/* Play the speci.fl.ed MetaFl.le to the PS using the default vl.ew matri.x to
/* scale and translate the output to fi.t a speci.fl.ed rectangle i.n the PS
/* page, whi.le preservl.ng the aspect rati.o of the pl.cture. Note that l.f the
/* output devi.ce i.s a pri.nter then 1.t i.s the responsl.bl.1l.ty of the caller
/* to i.ssue the 'start document' and lend document' escapes before and after
/* I.nvocati.on.
/*
/* i.nputs: hps PS handle
/* hmf MetaFl.le handle
/* prclTarget Target rectangle 1.n page coordi.nates
/*

#defi.ne NOPTI0NS (LONG)(PMF_DEFAULTS+1)


#defi.ne LDESC 256L

B00L fRet /* B00L return code


LONG Isegcount /* returned segment count
BYTE abDesc[LDESC] /* returned descri.pti.ve array
LONG alopns[NOPTI0NS] /* Gpi.PlayMetaF1.1e optl.ons
P0INTL ptlposn /* coordi.nate poi.nt
RECTL rclBoundary /* boundary rectangle
MATRIXLF matlfxform /* transform Matrix
FIXED afxscale[2] /* x and y scale factors

/* set di.splay control off


fRet = Gpi.SetDrawcontrol( hps /* -PS handle
DCTL_DISPLAY /* -draw control
DCTL_OFF /* -value
n
l`f (fRet) /* set bounds accumulati.on
fRet = GpisetDrawcontrol( hps /* -PS handle
DCTL_BOUNDARY /* -draw control
DCTL_ON /* -value
in

l'f (fRet) /* reset boundary data


fRet = Gpi.ResetBoundaryData(hps); /* -PS handle

/* set play MetaFi.le optl.ons


a l opn s [ PM F_S EGBAS E ] OL; /* -reserved
a l o pn s [ PM F_LOADTY P E ] LT_NOMODI FY : /* -transform opti.on
a l opn s [ PM F_RESO LV E ] OL; /* -reserved
a l opn s [ PM F_LC I DS ] LC_LOADDI SC ; /* -lc,'d Optl'On
a 1 0pn s [ PM F_RES ET] RES_NORES ET : /* -reset opti.on
a l opn s [ PM F_SU P P RESS ] SUP_NOSUPPRESS /* -suppress optl.on
a l opn s [ PM F_CO LO RTAB L ES ] CTAB_RE P LAC E ; /* -color table opti.on
a l opn s [ PM F_CO LO RR EA L I ZAB L E ] C R EA_NO REA L I Z E /* -color reali.ze opti.on
a l opn s [ PM F_D E FAU LTS ] DDE F_LOADD I SC ; /* -default attri.bute opti.on

Figure 11.6 ScaleMetaFile Function.


METAFILES 213

play the MetaFi.le to */


l'f (fRet) accumulate boundary data */
fRet = (B00L)Gpl.PlayMetaF1.1e( hps -PS handle */
hmf -MetaFi.1e handle */
NOPTI0NS -opti.on count */
alopns - 0 p t 1' 0 n S */
&lsegcount ret seg count (reserved) */
LDESC si.ze of descri.pti.ve array */
abDesc returned descri.ptl.ve array*/
in
l.f (fRet) uery the boundary data */
fRet = Gpl.OueryBoundaryData( hps PS handle
&rclBoundary boundary rectangle
in

/* Determi.ne scale parameters to scale from boundary di.mensi.ons to target */


/* di.mensi.ons about bottom left of boundary. Ensure that both scale */
/* factors are equal and set to the smaller of the two possi.ble values (to */
/* preserve the aspect ratl.o of the pi.cture). */

afxscale[0] = (prclTarget->xRl.ght -prclTarget->xLeft) * Oxl0000


/ (rclBoundary.xR1.ght -rclBoundary.xLeft):
afxscale[1] = (prclTarget->yTop -prclTarget->yBottom) * Oxl0000
/ (rclBoundary.yTop -rclBoundary.yBottom);

i.f (afxscale[0] < afxscale[1])


afxscale[1] = afxscale[0];
else
afxscale[0] = afxscale[1]:
ptlposn.x = rclBoundary.xLeft;
ptlposn.y = rclBoundary.yBottom;

l'f (fRet) /* obtai.n scall.ng matrl.x


fRet = Gpl.Scale( hps /* -PS handle
&matlfxform /* -transform matri.x
TRANSFORM_REPLACE /* -Optl'ons
afxscale /* -x and y scale factors
&ptlposn /* -center of scali.ng
in

Add requi.red translatl.on to translate from boundary bottom left to target */


I--J~+ _.. I _ fL
bottom left. */
Posn.x = prclTarget->xLeft -rclBoundary.xLeft
Posn.y = prclTarget->yBottom rcl Bounda ry . yBottom ;
( f Ret ) /* update matrl.x for translati.on
fRet = Gpi.Translate( hps /* -PS handle
&matlfxform /* -transform matri.x
T RA N S FO RM_A D D /* -optl'ons
&ptl Posn /* -translati.on

l.f (fRet) /* set default vi.ew matri.x


fRet = Gpi.SetDefaultvi.ewMatri.x( hps /* -ps i;naie-' .-..... u-'.'`
9L /* -number of matri.x elements
&matlfxform /* -transform matri.x
TRANSFORM_REPLACE /* -opti.ons

Figure 11.6 (co7i££nt/ecz)


214 OS/2 PRESENTATION MANAGER GPI

l'f (fRet) set bounds accumulati.on off*/


fRet = Gpl.SetDrawcontrol( hps -PS handle */
DCTL_BOUNDARY -draw control */
DCTL_OFF -val ue */
in

l'f (fRet) /* set dl.splay control on */


fRet = Gpi.SetDrawcontrol( hps /* -PS handle */
DCTL_DISPLAY /* -draw control */
DCTL_ON /* -value */
);

l.f (fRet) */
play MetaFi.1e
fRet = (B00L)Gpi.PlayMetaFi.le( hps -PS handle */
hmf -MetaFi.1e handle */
NOPTI0NS
-opti.on count */
alopns - 0 p t 1. 0 n s */
&lsegcount ret seg count (reserved) */
LDESC si.ze of descri.pti.ve array */
abDesc returned descri.pti.ve array*/
in

return (fRet);
)

Figure 11.6 (con££nzJecz)

/* subpi.cme.c */
B00L Subpi.ctureMetaFi.le(HPS hps, HMF hmf , PRECTL prclTarget)

/* Play the specifl.ed MetaFl.le to the PS as a subpi.cture usl.ng the vi.ewl.ng


/* transform matrl.x to scale and translate the output to fl.t a speci.fi.ed
/* rectangle l.n the PS page, regardless of the value of the default vl.ew
/* matrl.x. The background of the subpi.cture wi.ll be cleared to whi.te.
/*
/* The speci.fi.ed PS must be of type GPIT_NORMAL to allow use of
/* Gpi.Setvl.ewi.ngTransformMatrl.x and Gpi.Opensegment.
/*
/* It i.s assumed that the drawl.ng mode 1.s set to DM_DRAW (l..e. default value)
/* on 1.nvocati.on.
/*
/* It i.s assumed that the MetaFi.le 1.tself does not depend on any of l.ts own
/* 1.nternal vi.ewi.ng transform values for 1.ts correct appearance (as these
/* are I.gnored 1.n favour of the matrl.x provl.ded for subpl.cturl.ng).
/*
/* 1.nputs: hps PS handle (type GPIT_NORMAL)
/* hmf MetaF1.1e handle
/* prclTarget Target rectangle l.n page coordl.nates
/*

#defi.ne NOPTI0NS (LONG)(PMF_DEFAULTS+1)


#define LDESC 256L

Figure 11.7 SubpictureMetaFile Function.


METAFILES 215

B00L fRet /* B00L return code


LONG Isegcount /* returned segment count
BYTE abDesc[LDESC] /* returned descri.ptl.ve
LONG al0pns[NOPTI0NS] /* Gpi.PlayMetaFi.le opti.ons
P0INTL ptlposn /* coordi.nate poi.nt
RECTL rclBoundary /* boundary rectangle
MATRIXLF matlfxform /* transform Matri.x
RECTL rclTarget /* target rectangle
FIXED afxscale[2] /* x and y scale factors
stati.c MATRIXLF matlfldentl.ty = { Oxl0000, 0, 0, 0, Oxl0000. 0, OL. OL
/* set dl.splay control off
fRet = Gpl.SetDrawcontrol( hps /* -PS handle
DCTL_DISPLAY /* -draw control
DCTL_OFF /* -value
in
l'f (fRet) /* set bounds accumulati.on
fRet = Gpi.SetDrawcontrol( hps /* -PS handle
DCTL_BOUNDARY /* -draw control
DCTL_ON /* -value
in

l'f (fRet) /* reset boundary data


fRet = Gpl.ResetBoundaryData(hps); /* -PS handle

/* set play MetaFi.le opti.ons


a 1 0pn s [ PM F_S EGBAS E] OL; /* -reserved
a 1 0 pn s [ PM F_LOADTY P E ] LT_NOMOD I FY ; /* -transform opti.on
a l opns [ PM F_RESO LV E ] OL; /* -reserved
a 1 0pn s [ PM F_LC I DS ] LC_LOADD I SC : /* -lcl'd Optl`on
a l opn s [ PM F_RES ET] R ES_NO R ES ET : /* -reset opti.on
a 1 0pn s [ PM F_SU P P RESS ] SUP_NOSUPPRESS /* -suppress opti.on
a l o pn s [ PM F_CO LO RTAB LES ] CTAB_RE P LAC E ; /* -color table option
a l o pn s [ PM F_CO LO RR EA L I ZAB L E ] C R EA_NO R EA L I Z E /* -color reali.ze opti.on
a l opn s [ PM F_D E FAU LTS ] DDE F_LOADD I SC : /* -default attri.bute opti.on

play the MetaF1.1e to */


1'f (fRet) accumulate boundary data */
fRet = (B00L)Gpi.PlayMetaFi.1e( hps -PS handle */
hmf -MetaF1.le handle */
NOPTI0NS -opti.on count */
al0pns - 0 p t 1. 0 n S */
&lsegcount ret seg count (reserved) */
LDESC sl.ze of descri.pti.ve array */
abDesc returned descrl.pti.ve array*/
in

l'f (fRet) uery the boundary data */


fRet = Gpl.QueryBoundaryData( hps PS handle */
&rclBoundary boundary rectangle */
in
/* convert target rectangle coordi.nates from page to default page to allow */
/* for the effect of default vl.ew matrl.x on the target */

Figure 11.7 (co7i££nz/ed)


216 OS/2 PRESENTATION MANAGER GPI

rcl Ta rget . x Left prcl Ta rget ->x Left :


r c 1 T a r g e t . x R i. g h t prcl Ta rget ->xRi ght : /* convert target rectangle
rcl Ta rget . yBottom p rc l Ta rget ->yBottom /* coordi.nates from page to
rcl Ta rget . yTop prcl Ta rget ->yTop ; /* default page
l'f (fRet) /*
fRet = Gpi.Convert( hps /* -PS handle
CVTC_PAGE /* -source
CVTC_DEFAULTPAGE /* -target
2L /* -count of coordl.nates
(PP0INTL)(&rclTarget) /* -coordi.nate array
);

/* Determi.ne scale parameters to scale from boundary dl.mensl.ons to target


/* di.mensi.ons about bottom left of boundary. Ensure that both scale factors
/* are equal and set to the smaller of the two possi.ble values (to preserve
/* the aspect ratl.o of the pl.cture).

i.f (rclBoundary.xRl.ght > rclBoundary.xLeft) /* avol.d dl.vl.de by zero


afxscale[0] = (rclTarget.xR1.ght -rclTarget.xLeft) * Oxl0000
/ (rclBoundary.xRi.ght -rclBoundary.xLeft);
else
afxscale[0] = Oxl0000: /* 1.0

I.f (rclBoundary.yTop > rclBoundary.yBottom) /* avoi.d di.vi.de by zero


afxscale[1] = (rclTarget.yTop -rclTarget.yBottom) * Oxl0000
/ (rclBoundary.yTop -rclBoundary.yBottom):
else
afxscale[1] = Oxl0000: /* 1.0 */

I.f (afxscale[0] < afxscale[1])


afxscale[1] = afxscale[0]:
else
afxscale[0] = afxscale[1]:
ptlposn.x = rclBoundary.xLeft;
ptlposn.y = rclBoundary.yBottom:

l'f (fRet) /* obtai.n scali.ng matri.x


fRet = Gpl.Scale( hps /* -PS handle
. &matlfxform /* -transform matri.x
TRANSFORM_REPLACE /* -Optl.Ons
afxscale /* -x and y scale factors
&ptlpos-n /* -center of scall.ng
):

/* Add requi.red translation to translate from boundary bottom left to target */


/* bottom left. */

ptlposn.x = rclTarget.xLeft -rclBoundary.xLeft:


ptlposn.y = rclTarget.yBottom -rclBoundary.yBottom
1'f (fRet) /* update matri.x for translati.on
fRet = Gpl.Translate( hps /* -PS handle
&matlfxform /* -transform matrl.x
. TRANSFORM_ADD /* -Optl.Ons
&ptlposn /* -translati.on
n

Figure 11.7 (co7i£Z7?I/ec!)


METAFILES 217

i.f (fRet) /* set vi.ewi.ng transform matri.x


fRet = Gpi.Setvi.ewi.ngTransformMatrl.x( hps /* -PS handle
9L /* -number of matri.x elements
&matlfxform /* -transform matri.x
TRANSFORM_REPLACE /* -opti.ons
in

l'f (fRet) set bounds accumulati.on off*/


fRet = Gpl.SetDrawcontrol( hps -PS handle
DCTL_BOUNDARY -draw control
-val ue
. DCTL_OFF
in

l'f (fRet) /* set dl.splay control on


fRet = Gpi.SetDrawcontrol( hps /* -PS handle
DCTL_DISPLAY /* -draw control
DCTL_ON /* -value
in

1.f (fRet) /* reset model transform matri.x


fRet = Gpi.SetModelTransformMatrl.x( hps /* -PS handle
9L /* -number of matri.x elements
&matlfldentl.ty /* -transform matrl.x
TRANSFORM_REPLACE /* -opti.ons
in

/* clear subpi.cture rectangle to whl.te before playl.ng the MetaFile to draw */


/* the subpl.cture. */

open segment zero to set */


I.f (fRet) vl.ewl.ng transform attrl.bute*/
fRet = Gpi.Opensegment( hps PS handle */
OL segment l.d (zero) */
in

l'f (fRet) /* set color to whi.te */


fRet = Gpi.Setcolor( hps /* -PS handle */
CLR_WHITE /* -color */
n
Posn.x = rclBoundary.xLeft:
Posn.y = rclBoundary.yBottom; /* set current posl.ti.on to */
/* boundary bottom left */
fRet = Gpi.Move( hps /* -PS handle */
&ptlposn /* -coordi.nate poi.nt */
n
Posn.x = rclBoundary.xRi.ght;
Posn.y = rclBoundary.yTop;
/* clear boundary rectangle
fRet = (B00L)Gpi.Box( hps /* -PS handle
DRO_FILL /* -control
&ptlposn /* -corner coordi.nate pol.nt
OL /* -roundl.ng
OL /* -roundi.ng
in

Figure 11.7 (co7?£}7}L4ecz)


218 OS/2 PRESENTATION MANAGER GPI

1'f (fRet) /* close segment


fRet = Gpi.Closesegment(hps): /* -PS handle

l'f (fRet) /* set color to default


fRet = Gpi.Setcolor( hps /* -PS handle
CLR_DEFAULT /* -color
in

/* now play the MetaF1.le to draw the subpi.cture */

alopns[PMF_LCIDS] = LC_NOLOAD; /* -lci.d opti.on */


alopns[PMF_DEFAULTS] = DDEF_IGNORE; /* -default attrl.bute opti.on */
l'f (fRet) /* play MetaFi.le */
fRet = (B00L)Gpl.PlayMetaFl.1e( hps /* -PS handle */
hmf /* -MetaFi.le handle */
NOPTI0NS /* -opti.on count */
alopns /* -Optl'Ons */
&lsegcount /* -ret seg count (reserved) */
LDESC /* -si.ze of descri.pti.ve array */
abDesc /* -returned descrl.ptl.ve array*/
in

return (fRet);
)

Figure 11.7 (co7?££7}ztecz)


Printing

Throughout this chapter, the term printing is used to refer to both printing and
plotting. Also, in the examples, the terminology used for queue and printer names
is taken from IBM OS/2 Version 1.2 rather than 1.3. Queue names, for example,
are called LPI`1Q, LPI`2Q, COMIQ , and so forth, and printer names PRINTER1,
PRINTER2, PLOTI`ER1, and so forth. This scheme is followed in order to ensure
that queue names are distinct from printer names. Such a naming scheme can be
employed on Version 1.3, but by default, a queue and printer will both have the
same name (e.g., LASER1).
OSA provides a variety of different ways of printing enabling an end user or an
application to print:
• Gpi graphics and text.
• Raw (device dependent) printer data.
• Data in some other format unique to a particular print queue proces-
sor or queue processor and driver.
For many printer drivers, raw printer data is the same as raw ASCII text,
although raw printer data may include additional escapes that are specific to a
particular printer. The main exception is the Postscript driver ®script.drv), which
has its own unique format for raw data and does not currently support printing of
raw ASCII text.
Hrint operations can be either direct or queued (i.e., printed via the spooler).

DIRECT PRIHTIHG (DC TYPE: OD DIRECT)

With direct printing, data is output directly from an application (via the print
drivers) to the printer, bypassing the print queue. This method is used by the
system for printing queued print files when they are dequeued (see below).

219
220 OS/2 PRESENTATION MANAGER GPI

Direct printing is not really intended for norm.al application use. In a multi-ap-
plication system such as OSA, different applications may be attempting to print
concurrently. With direct (application) printing this could allow interference be-
tween print jobs from different applications, or force an end user to wait for
completion of one print job before being able to initiate another from the same
application.
If the OSA Spooler is disabled using the nrint Manager then this will force all
queued printing to be direct.

QUEUED PRIMTIHG (DC TYPE: OD_OUEUED)

With queued printing, print data is intercepted by the Spooler, accumulated in a


print file and enqueued on the print queue. I}rint files from all sources are
dequeued from the print queue according to job priority, passed to the appropriate
print queue processor, and printed by the system (using direct printing) on the
appropriate printer. This is the normal mode of printing applications should use
whenever possible.
Early versions of some applications may recommend that the Spooler be dis-
abled, effectively converting all queued printing to direct. This advice should be
ignored unless problems are encountered. Most problems with the Spooler and
drivers on early releases of OSA were coITected by CoITective Service Diskettes
(CSDs)andsubsequentreleases.Anyremainingproblemsarelikelytobethefault
of the application, in which case it may be necessary to obtain a colTected version
of this. The Spooler should only be disabled as a last resort.

TYPES OF PRIHTIHG

OSA provides many different ways of initiating a print operation, all of which use
one of the following three types of printing.

Base Control Program Prfnt]ng

Base Control Hogram printing includes any of the following operations:


• DosopenqpT1) - Doswrite - Dosclose (application request).
• Dos Mode Int 21 and BIOS Int 17 (application request).
• Hint command (user request).
• Copy file LPI`1 (user request).
• I+int Screen Key (user request).
• Redirection using >prm (user request).
If the Spooler has not been disabled, all Base Control Hogram print jobs are
queued.
PRI NTI NC TZ1

Presentat]on Manager Pr[ndhg


Hesentation Manager printing is the method used by most PM applications,
including the File Manager and the a]E) Comlnunication Manager. The PM API
calls support both direct and queued printing and can be used with any of the
following data types:
"PM_Q_RAW" (raw device dependent format)

As mentioned above, for most printers, the PM_Q_RAW form.at is


the same as raw ASCII tezit with additional embedded escapes pro-
viding the required device specific printer controls. Hinting with
this format can be accomplished using only Dev functions.
"PM_Q_STD" (standard graphics format)

This is standard graphics format supporting any GPI graphics


and text output.
The intention of PM_Q_STD, as opposed to PM_Q_RAW, format is
to enable the format of print files to be device independent, theoreti-
cally allowing them to be printed on any type of printer. This could
eventually enable printer pooling with different printer types, but it
is not currently possible to properly exploit this feature. In practice,
PM_Q_STD print files may contain certain device dependencies. For
example, they might reference device fonts or be dependent on de-
vice resolution. OS# therefore tags each print ].ob with the print
driver and device name, forcing it to be printed on the correct device.
Although printer pooling using different printer types is not cur-
rently supported, printer pooling using printers of the same type is
possible.
A disadvantage of the PM_Q_S'ID format is that any fonts used
by an application must be installed as public fonts on the local sys-
ten for local printing, or on the print server node for network print-
ing. Although PM_Q_RAW format does not have this restriction,
PM_Q_STD is the recommended format.
PM_Q_STD format is based on, and closely resembles a MetaFile.
A MetaFile can be enqueued as a PM_Q_STD print file using the
Spooler Function Calls (see below). A PM_Q_S'ID print file can also
be drawn using GpiplayMetaFile. These two formats are not, how-
ever, identical. A MetaFile will not necessarily contain all the
printer control information that a PM_Q_STD print file contains
and a PM_Q_STD print file may not correctly conformi to the MetaF-
ile interchange architecture. In particular, if logical fonts are cre-
abed using lMatch (see chapter 4), the lMatch value will be recorded
in a PM_Q_S'ID print file but not in a MetaFile. In addition, the
DevEscape codes recorded in a PM_Q_S'ID print file will differ from
ZZZ 0S/2 PRESENTATION MANAGER GPI

those recorded in a MetaFile (depending on the escape code value).


Although cuITently these are the only real differences, it is possible
that other differences will be added in the future.
Other Strings
Other strings can be used to specify special formats unique to the
queue processor or both queue processor and a particular print
driver.

Spooler (SpD Function Calls (Spooler APD


The Spooler Function Calls (e.g., SplQmopen) enable print files to be enqueued to
the print queue and are primarily for use by the System and presentation drivers
rather than by applications. The valid print file data types are those supported by
the specified (or default) print queue processor and can be queried using the
SplQPQueryDt function. For PMPRINT (the default OSA print queue processor)
valid data types are:
• "PM_Q_RAW" (raw device dependent format as described above)
• "PM_Q_STD" (standard graphics format as described above).
• Other Strings specifying queue processor specific formats. These
may be unique to the queue processor or to a queue processor and a
particular presentation driver.
Although the Spooler Function Calls primarily exist for use by the System and
presentation drivers, they also provide applications with a means of adding raw
print data files or MetaFiles directly to the print queue, bypassing some of the
application overheads associated with printing using Base Control nrogram and
GPI calls. Note however that, as described above, the PM_Q_STD and MetaFile
formats are not identical. Real PM_Q_STD print files, as opposed to MetaFiles,
are created by the system in response to appropriate Dev and GPI functions and
are discussed in the remainder of this chapter.
The Spooler Function calls closely parallel the equivalent set of Dev functions
and, with a good understanding of the latter, use of the Spooler Function calls is
relatively straightforward.

OS/2 PRINT SUBSYSTEM

The OSA Hrint Subsystem is illustrated in Figure 12-1 and shows the Spooler
Function Calls and the Base OSA File System (Base Control I}rogram I+inting)
outputbeingpassedtothespoolQueueManagerforenqueueingontheprintqueue.
Conceptually at least, presentation drivers consist of two parts. Hesentation
Driver (I) handles recording the data in the print file and Hesentation Driver (11)
handles the output to the printer. The output from PM print operations follows one
of two paths depending on whether printing is direct or queued. Direct output goes
directly to Hresentation Driver (11) for immediate printing, whereas queued output
PRINTING 223

PRESENTATION MANAGER PRINTING

->)>)ThoLPRIPta)S)CmFUNC
DevopenDC-
(OD.DIRECT
PMGPI
J
Present.tion Pro.ontation
D®vopenDC > Drlv®r (I) > Driver (11)
(OD_QUEUEI)

Hana8®r
Qu.u.
proce8aor
t[an&8er PMPRINITI3::i: . IPrintQu®u®[§p=::.qu.u.I
843® PrintI)ovlceI)riverBASEDD02.SYS

ING BaseOS/2>F1|®SyEtaaTI0NCALlis

Dosopen(LPT
Doswrlt®
Doacloae

INT17 (D0

PRINT Crm

COPY LFTI

Prtsc Key
Cro >pm

SPcOLER

i -I ±±
Spl API

Print®r3
Figure 12.1 0SA nrint Subsystem.

goes via the Hesentation Driver (I) to the Spool Queue Manager for enqueueing
on the print queue.
As mentioned earlier, queued operation print files from all applications are
removed from the print queue in turn, according to their priority, and printed by
the system using direct printing. All print jobs, both direct and queued, eventually
reach Fkesentation Driver (11) before being passed to the Base Print Device Driver
for printing. This enables the presentation driver, as a minimum, to reset the
driver between jobs, canceling any job related conditions remaining from the
T24 0S/2 PRESENTATION MANAGER GPI

previous job, and also enabling it to set any relevant job options (e.g., print quality,
number of characters per inch) required for the next job.
A ].ob in the print queue will only print if its `driver.device' name matehes that
of a printer associated with the queue, the printer is connected to a valid port, and
the form code specified for the job is either selectable or current (see below). If all
theseconditionsaresatisfied,thenthejobwiththehighestpriorityforaparticular
printer will be printed first on that printer.
If raw printer data is being printed and the reset between jobs is not required
®ecause, for example, the end user does not want the printer switch settings to be
overridden) then the IBENUIL driver, provided for this purpose, should be used.
In practice, I+esentation Drivers (I) and (11) do not normally exist as separate
components but they do provide a useful model for illustrating the operation of
direct and queued printing.

PRINTER IHSTALLATIOH AHD SET UP

Although printer installation is a large and complex topic and is mainly outside
the scope of this book, an understanding of the underlying model is important.
Hinter presentation drivers (some of which have dot-qualified device names,
e.g., LASERJET.Iip LaserJet 11, PLOTTERS.IBM6180) are installed using the
Control Panel or nrint Manager.
FTinter set up involves establishing associations between:
• A printer name (e.g., PRINTER1).
• A single port or logical address (e.g., LPI'1).
•One or more presentation driver names (e.g., IBM4019,
PSCRIPT.QMSTMPS810Th) for use with this printer, with one of
these selected as the default.
and for the queue between:
• A print queue name (e.g., LPI`1Q).
• A default print queue processor name (e.g., PMPRINT).
• One or more printer names (e.g., PRINTER1, PRINTER2).
• A default presentation driver name for this queue (this must be one
that is associated with this printer name but need not be the same as
the above default for this printer).
Queue set up also establishes the first queue associated with a printer name as
the default queue for this printer.
A print queue and printer name can also be specified as application defaults. The
application default printer need not be one that is associated with the default
queue.
Hinter set-up examples are shown in Figures 12-2 and 12-3. The set up can be
very simple as illustrated in Figure 12-2, with just a single queue associated with
a single printer and presentation driver. Altematively, it can be complex as
illustrated in Figure 12-3, with multiple queues, multiple printers, and multiple
PRI NTI NG TZ5

QUEUE PRINTER PRESENTATION PORTS


(vlth d®f.ult DRIVERS
Queue Proc®8aor)

LPTIQ(PHPRINI) > PRINTER|

printer
d®f®ult
qu®u®

queue
d®f&ult
driver

Figure 12.2 I}rinter Set Up Example 1.

presentation drivers. This more complex set up provides a number of additional


useful features:
• The same presentation driver may be associated with more than one
printer name, enabling the same type of printer (and driver) to be
used on more than one port.
•A printer name can have more than one associated presentation
driver. This is useful, for example, if the port is switchable between
different printer types, or for network printing, where the port is
redirected (e.g., using "net use") to a 'queue on a remote print server
node, where the remote queue supports different printer types.
• Different queues can be associated with the same printer name. This
is called I+inter Sharing and is useful if a choice of print ].ob proper-
ties is required without end user intervention. With such a configu-
ration, an application is able to vary the job properties merely by
switching queues. One queue, for example, could be set for landscape
and another for portrait printing, with both queues sharing the same
printer name, driver, and port.
• A single queue can be associated with different printer names. This
is called Hinter Pooling and enables the same queue to be used for
printing to different ports (the only presentation drivers available as
defaults for this queue are those associated with all associated print-
ers). This configuration is useful for a print server queue providing a
pool of printers for use by the network. A pool of different printers
will provide a choice of printer type whereas a pool of identical
printers can be used to provide faster throughput of print jobs.

HErvoRK pRiHTIHG

For network printing from a requester to a remote print server, server queues and
printers are not visible to a requester application except by using the DosF+int API
(see below). It is not, therefore, possible for a requester application to open a DC
226 OS/2 PRESENTATION MANAGER GPI

QUEUE PRINTER PRESENTATION PORTS


(with default DRIVERS
Qu®u® Processor)

COMIQ("PRINI) > PL0mR1

printer
default printer
queue default
drlv®r
pLomRs . IBM6 180
queue
de£&ult
driver

IBM4019

PSCRIPT.QMS-PS810

LASERJET.HP La8®rJot Plus

LASERJET.HP LIB®rJet Ilo

I.ASERJET.HP La8erJ®t IIP

IASERJET.HP LasorJet Plus

LASERJET.HP LaserJet 2000

Figure 12.3 1lrinter Set Up Example 2.

for a server queue or port. The server must share a printer queue (e.g., using net
share lptlq/print) and the requester must alias the server queue as one of its ports
(e.g., using net use lpt4 \\server_name\lptlq). nrovided both print requester and
server are correctly set up, network printing on a remote print server node can be
made transparent to an application initiating print requests from the requester.
To achieve this, the server and requester must set up as follows:
PRINTING 227

• The presentation `driver.device,' printer properties, and forms code


specifiedfortherequester(local)queueandprintermustmilTorthose
of the server queue and printer. This ensures that values used by a
requester application are compatible with the server (the application
continuestoprintusingonlythelocaldummyqueueandprinterport,
unaware that its output is being redirected across the LAN).
• The server queue network options (for IBM OSA Version 1.2) should
include a `DRIVER=' statement (e.g., DRIVER="PLOTTERS.IBM
6180"). This is not essential for nresentation Manager printing as the
jobs include this information, but Base Control Hogram print jobs
require this in order to identify the presentation driver. A typical set
of 1.2 server queue network options might be:

DRIVER="IASERJET.IIf LaserJet IID" AFTER=09:00


BEFORE= 10:cO SEPARATOR="C: \SEP\IBMSEP. SEP"

Here the AFTER and BEFORE keywords identify the times at which printing may
occur and the SEPARATOR keyword identifies the name and location of the
separator definition file. Note that separator files for most print drivers use ASCII
text, but pscript drivers currently require separator page text to be defined using
the Postscript language. Network options are not required by the requester queue.
Note that on IBM Ospe EE Version 1.3 these are no longer referred to as network
options and are specified using individual dialog control windows rather than as
a single string of network options.

PRESEHTATIOH MANAGER PRIHTIHG FROM AH APPLICATION

I+esentation Manager printing from an application is probably best described in


terms of the sequence of operations required. The steps are as follows:
1. Establish a queue name for queued printing or port name for direct
printing and the presentation driver and device names.
2. Establish the DRIVDATA (driver data) structure for the driver and
device.
3. Open an oD_QUEUED Dc for queuedprintingor an oD DIRECTDC
for direct printing.
4. Createaps.
5. Associatethe ps andDC.
6. Start the document by issuing a `start document' DevEscape.
7. Output the document or picture contents using Gpl functions.
8. End the document by issuing an `end document' DevEscape.
9. Dissociatethe ps andDC.
10. Destroytheps.
11. ClosetheDC.
For raw data, no PS is required and the sequence is therefore:
T2B OS/2 PRESENTATION MANAGER GPI

1. Establish a queue name for queued printing or port nam.e for direct
printing and the presentation driver and device names.
2. Establish the DRIVDATA (driver data) structure for the driver and
device.
3. Open an oD_QUEUED Dc for queued printing or an oD DIRECTDC
for direct printing.
4. Start the document by issuing a `start document' DevEscape.
5. Output the raw data using `raw data' DevEscapes.
6. End the document by issuing an `end document' DevEscape.
7. ClosetheDC.
In addition, `new frame' and `abort document' DevEscapes may be used ®etween
the `start document and `end document' DevEscapes) to staid a new page or to abort
the print operation respectively.

Establ[sh[ng the Queue, Port, Dr]ver, Dev]ce, and DRIVDATA

There are currently two main methods of establishing queue name, port name,
driver name, device name, and the DRIVDATA structure, one based on printer
selection and the other on queue selection.

Printer Selection Method

With this method, the application is unable to vary the job properties for a printer
withoutenduserintervention.Itdoes,however,enabletheapplicationtooptionally
provide the user with a driver dialog on a `per job' basis, allowing the user to specify
printer properties as well as job properties and also update the INI file if required.
This method requires the application first to select a printer name and then use
this to determine:
port name (required only for direct printing);
presentation driver name for this printer;
device name for this driver; and
queue name (required only for queued printing).
The printer name is established either by querying the default printer name or by
querying a list of all available printer names and selecting one of these.
1. The default printer name is determined using:

I}rfQueryHofile s tring (Applic ation= "PM_S POOLE R'' ,


Key="PRINTER").

This returns a null terminated printer name of the form:


PRINTER1;
PRI NTING ZZ9

This is illustrated by the function QueryDefaultF+inter in Figure 12-4


(which removes the `;' replacing it by null). The list of all available
printer nalnes is determined using:

I}rfQueryHofile string (Applic ation= "PM_S POOIE R_PRINTER'',


Key=NULL).

This returns a list of printer names of the form:


PRINTERI PRINTER2 PRINThR3 PLOTI`ERI
Each printer name in the list is terminated by a null with the final
name terminated by two mulls. This is illustrated by the function
QueryprinterNames in Figure 12-5.
2. Having obtained a printer nalne, this is used to determine the port,
driver, device and queue names. These are determined using:

HfQueryHofilestring (Application="PM_SPOOLER_PRINTER",
Key=frinter name).

This returns a null terminated string containing the port name, one or
more driver names (with or without dot qualified device names), and
one or more queue names. The names of the default driver and queue
for the printer are those returned first. The returned string will be in
one of the the following forms:
LFT1;IBM4019;LFTIQ;;
Or

COM1;PLOITERS.IBM6180;COMIQ;;
Or

LFT1;IIASERJET.HP Laserjet Plus, PSCRIFT.QMS-PS810,


IBM4019;LFTIQ,LFT12Q;;
The final semicolon is intended to delimit a parameter string that is
currently unused. This is illustrated by the function QueryFTinterlnfo
in Figure 12-6, which separates the above string into a number of
individual null terminated strings.
3. The driver and device name are used with the printer name to obtain
the DRIVDATA structure using DevpostDeviceModes. DevpostDevice
Modes includes an options parameter allowing the application to
specify one of the following:
DPDM POSTJOBPROP provides the end user with a dialog
controlling job properties. This can also be used with a NULL
P+inter Name to allow the user to modify an existing
DRIVDATA structure via the Job Properties dialog as described
below for the Queue Selection Method.
230 OS/2 PRESENTATION MANAGER GPI

DPDM_CHANGEPROP provides the end user with a dialog


controlling both job and printer properties and the INI file is
updated to reflect any changes.
DPDM_QUERYJOBPROP provides no dialog to the end user;
the job and printer properties used are the defaults from the INI
file.
DevpostDeviceModes should actually be issued twice, once with a
NULL DRIVDATA pointer to determine the amount of memory re-
quired and a second time, having allocated the memory, to obtain the
DRIVDATA structure. This is illustrated by the function
PostDeviceModes in Figure 12-7.

Queue Selection Method


This method obtains a DRIVDATA structure based on the print job properties
associated with a specific print queue. This enables an application to vary job
properties (such as portrait#andscape) for a printer on a `per job' basis without
user intervention. This is accomplished by the application selecting the queue with
the required job properties from one of a number of queues associated with the
sane printer.
With this approach, the application does not obtain (or require) the port and
printer name. Unless the the spooler is disabled, it cannot be used for direct
printing. Also, without performing additional queries, an application has no
absolute guarantee that the selected queue has an associated port and will print
successfully ®ort selection is controlled by nrint Manager set up).
This method requires the application to first select a queue name and use this
to determine the name of the default presentation driver for the queue. The queue
name is established either by querying the default queue name or by querying a
list of all available queue names and selecting one.
1. The default queue is determined using:

HfQueryHofile string (Applic ation= "PM_SPOOIER'',


Key ="QUEUE").

This returns a null terminated queue name of the form:


LFTIQ;
This is illustrated by the function QueryDefaultQueue in Figure 12-8
(which removes the `;' replacing it by null). The list of all available
queue names can be determined using:
HfQueryHofilestring (Application = "PM_SPOOLER_QUEUE",
Key = NULL).

This returns a list of queue names of the form:


LFTIQ LFT2Q LFT23Q COMIQ
PRINTING 231

Each name in the list is terminated by a null with the final name
terminated by two mulls. This is illustrated by the function
QueryQueueNames in Figure 12-9.
2. Having obtained a queue name, this is used to determine the default
presentation driver name for the queue and, where applicable, the
device name. The default driver name and device name for the queue
are determined using:

frfQueryHofilestring (Application="PM_SPOOLER_QUEUE_DD",
Key=queue name).

Depending on the driver concerned, this returns either a null termi-


nated driver name or driver.device name of the form:
IBM4019;
Or

PSCRIFT.QMS-PS810;
This is illustrated by the function QueryQueueDriver in Figure 12-10
(which removes the `;' and `.' replacing them by null).
3. The driver name is used with the queue name to obtain the
DRIVDATA structure using:

PrfQueryfrofilestring (Application= "PM_SPOOLER_QUEUE


DDDATA", Key=queue name).

This is illustrated by the function QueryQDriverData in Figure 12-11.


4. This next step is optional. The end user can nowbe provided with aJob
FTopertiesdialogenablingthequeuejobpropertiestobemodified.This
is accomplished by passing the DRIVDATA structure obtained above as
a parameter to DevpostDeviceModes with the DPDM POSTJOBPROP
option. This will return the DRIVDATA structure modified by the end
user selections. This method may not be supported by all drivers, some
of which may return an eITor. If an error is returned, the unmodified
DRIVDATA structure can be used and the eITor ignored. This is
illustratedbythefunctionPostlobHopertiesinFigure12-12.
In addition to the printer and queue selection methods described above, there are
two additional methods of defining the DRIVDATA structure described in Appen-
dix 1, neither of which are recommended. These both cause all ].ob and printer
properties to be defaulted.

Opening the DC and Pr]nt]ng

Having obtained the port or queue name and DRIVDATA structure using one of
the above methods, it is now possible to open a DC and complete the print
operation (using these as parameters to DevopenDC). The functions
T32 0S/2 PRESENTATION MANAGER GPI

nrintDefplinter and I}rintDefQueue in Figures 12-13 and 12-14 illustrate the


Queue Selection and I}rinter Selection methods for PM printing. The function
I+intRawData in Figure 12-15 illustrates printing raw data using the Hrinter
Selection method although the Queue Selection method would be equally valid.
By capturing the display screen in a bitmap and inserting appropriate GpiBitBlt
calls in either of the above @rinter or Queue Selection) methods, a print screen
operation can be performed.
By opening a file and drawing the ASCII text (as GPI character strings) in either
of the above PM printing functions, an ASCII file can be printed as GPI tezit to any
printer (e.g., see IlrintTextBuffer in Figure 1-5.).
By opening a file and outputting the ASCII text in the nrintRawData function,
an ASCII file can be printed as raw text to most printers Out not pscript).

FORM SELEOTI0H

An application wishing to use the Current Form for a printer need not be
concerned with fo]rm. selection. The Current Fo]rm. will be selected automatically
using the DRIVDATA structure obtained by one of the methods described above.
Certain printers, such as those with multiple paper trays, allow the Fo]rm. to be
switched on a `per job' basis without intervention at the printer. This type of fo]rm.
selection can be accomplished in one of two ways:
1. Using DevpostDeviceModes as described above, with options of
DPDM_CIIANGEPROP or DPDM_POSTJOBPROP, the operator can
select the required fo]rm. for each job via the Job Hroperties dialog.
2. The application can query a list of all available forms using
DevQueryHardcopycaps. This is another function that is actually
issued twice, once to determine the number of forms and, having
allocated the required memory, a second time to obtain the form.s
information. The forms are returned as an array of HCINFO struc-
tures each containing fo]rm. name, dimensions, and attributes. The
attributes for each returned form specify HCAPS_CURREP`IT (form is
curent), HCAPS_SEIECTABLE (form is selectable) or neither of
these. The application may choose any fo]rm name with the
HCAPS SELECTABIE or HCAPS_CURRENT flag set and specify
this in tie DEVOPENSTRUC pszSpoolerparams of DevopenDC (see
Appendix 1). A job with a fo]rm name that is neither cuITent nor
selectable will stick in the print queue and not print.

PR"T QUEUE PROCESSOR (OIJEIJE DRIVER) SELECTION

The print queue processor (or queue driver) is responsible for interpreting the
queue processor parameters and outputting a dequeued print file to the printer.
A queue processor name is not required for direct printing and applications
PRINTING T33

using queued printing, if they have no special requirements, should default this
parameter ®y specifying NULL for the DevopenDC DEVOPENSTRUC
pszQueueHocName field). The following description of queue processor selection
applies only to those applications with special queue processor requirements.
Although a default print queue processor (PMPRIN'I) is provided and installed
with OSA, certain applications with special needs may require an alternative. For
example, an application sending output to a plotter may wish to use the PMPLOT
queue processor to performi hidden line removal or reverse clipping. Additional
queue processors can be installed using the Control Panel (Add Queue Driver
menu option) or the Dost.oadModule and SplQplnstall functions.
It is important when installing and deleting queue processors to ensure that the
default queue processor is always one that is suitable for normal printing. This
enablesapplicationstousethisdefaultforgeneralprintingwithouttheneedtoissue
a query, specify a name, or be aware of different queue processor characteristics.
When necessary, an application can query the installed queue processors using:

frfQueryfrofile string (Application= "PM_S POOLE R_QP',


Key=NULL)

This returns a list of queue processor names of the form:


pMPRn`IT PMPLOT M¥QPRoc
Each name is terminated by a null with the final name in the list terminated by
two nulls. This is illustrated by the function QueryQueueHocessors in Figure
12-16.

PM_a_STD PRIHTIHG RESTRICTIONS

As explained earlier, PM_Q_S'ID print files are based on, and closely resemble
MetaFiles, and like MetaFiles, certain restrictions apply when they are being
recorded. Uhlike MetaFiles, Hint files need not conform to the interchange
architecture but some restrictions are necessary in order to preserve picture
integrity.
The following mles and guidelines apply to OD_QUEUEDflM_Q_STD printing:
1. All non-device fonts used in the picture must be installed as public
fonts on the local system for local printing or on the print server for
network printing.
2. IMatch (match number) should not be used for logical font creation if
printingistotakeplaceonadifferentnetworknodefromtheinitiating
application or if it is to be deferred until after a re-IPL. IMatch values
are only valid in the local system for the duration of the current IPL
session.
3. If logical font creation without lMatch is used, `scale to fit' options on
DevopenDC queue processor parameters should be avoided (i.e., spec-
ify XFM=0).
234 OS/2 PRESENTATION MANAGER GPI

4. If GpiBitBlt (as opposed to GpiwcBitBlt) is used, `scale to fit' options


on DevopenDC queue processor parameters should be avoided (i.e.,
specify XFM=0). It the output is scaled to fit then the BitBlt output
may be incoITectly positioned relative to the remainder of the picture.
5. Bitmaps should not be modified after their first use.
6. GpiDeleteBitmap should not be used until picture construction is
complete.
7. GpiDeletesetld should not be used until picture construction is com-
plete.
8. Gpisetps (or GpiplayMetaFile with the RES_RESET option) must not
be used after association with an OD_QUEUEDflM_Q_STD DC. This
will retu]m an eITor.
9. Gpisetpageviewport will be ignored.
10. Large pM_Q_STD print jobs with many pages in the same job should
be avoided if possible. Currently, these create a large temporary file in
memory during print file recording. This can significantly degrade
perform.ance and, in some cases, produce an `out of memory' condition.

PRINTER F0IITS

The FTesentation Manager provides certain multi-purpose font files (courier.fen,


times.fon, etc.) containing raster fonts with various point sizes and different device
resolutions. Certain drivers are unable to display raster fonts at all, including
those from these multi-purpose font files. This applies to the plotter and pscript
drivers.
In addition to the PM multi-purpose fonts and built in' printer device fonts,
certain printers offer a range of additional installable device fonts. These can
include both soft fonts (i.e., fonts installed from diskette) and card or cartridge
fonts. In either case, font definition (which defines the actual font cartridges
installed) and soft font installation is performed using the nr.int Manager driver
dialogs. As well as the files and cartridges that provide the actual font glyph
definitions for the printer, additional files are required for both soft and card/car-
tridge fonts to provide the corresponding font metric information. The font metric
information is that which is returned to an application by GpiQueryFonts and
GpiQueryFontMetrics to identify the metrics (or attributes) of these fonts to an
application.
Each print driver defines its own method of providing and installing soft and
card/cartridge font files.
The IIASERIET driver uses .FP`IT files for the font metrics. Initially, on version
1.2, these were supplied in packed fo]rm as .PCM files and later as individual .FNT
files. New card or cartridge fonts purchased separately should be supplied with a
.TFM file that can be unpacked to generate the .FNT files for these fonts.
The IBM4019 uses .FMF and .CDF files that are distributed as a single .PMF
file. The PMF files are unpacked into multiple FMF and CDF files by invoking the
Install Initial Metrics-Font Cards dialog.
PRI NTI NG T35

Some printers may also offer additional matching display fonts to provide
consistency between display and printer text appearance (this is sometimes
referred to as What-You-See-Is-What-You-Get or WYSIWYG).
As each raster font must be selected to match the resolution of the output device
and matching raster fonts do not exist for every device, WYSIWYG using raster
fonts is often difficult to achieve. This is not a problem with outline fonts that can
be used on any device. The Adobe Type Manager provided with IBM OSA Version
1.3 should make WYSIWYG possible using high quality outline font characters on
any output device.

BITMAP AND METAFILE PRIMT"G

When using Bitmaps and MetaFiles with printers, certain restrictions apply. Also,
bitmap inversion can occur under some conditions. For a discussion of bitmap and
MetaFile printing, see chapters 5 and 11.

DOSPRIHT SPOOLER API

The DosFTint Spooler API is included in IBM OSA Version 1.3 and provides three
groups of new functions:
Hint Destination Functions (e.g., DosnrintDestAdd)
These begin with the prefix DosHrintDest and enable named print-
ers to be queried, updated, created, deleted, and modified from an
application program as well as by nrint Manager set up.
Queue Destination Functions (e.g., DosHrintQAdd)
These begin with the prefix DosnrintQ and enable named printer
queues to be queried, updated, created, deleted, and modified
from an application program as well as by Ilrint Manager set up.
ELint Job Functions (e.g., DosprintlobDel)
These begin with the prefix Dosllrintlob and enable named print
jobs to be queried, updated, paused, restarted, and deleted from
an application program as well as by Ilrint Manager set up.
These functions are very powerful as, with a suitable privilege level, all opera-
tions can be performed on a remote server node as well as on the local system.
These functions all include a level number that determines the amount of data
ret-ed.
There is some overlap between these and the HrfQueryHofilestring functions
described earlier and some of the string parsing complexities associated with the
latter are eliminated. DosFhintDestEnum, for example, can be used to query (or
enumerate) the available printer names, their logical address, and the drivers
selectedforeachprinter.DosllrintQEnumcanbeusedtoquery(orenunerate)the
236 OS/2 PRESENTATION MANAGER GPI

available queue names, the names of the printers connected to each queue, and
the default driver (and its DRIVDATA structure) for each queue. Unlike
nrfQuerynrofilestring, however, these functions cannot be used to obtain the
application default queue and printer names.

qdefprtr.c */
Q u e r y D e f a u 1 t P r I. n t e r ( V 0 I D )

Return the default pri.nter name.

returns: PSZ Default pri.nter name or NULL (error or not found).


Thi.s functi.on null termi.nates the stri.ng removi.ng the ':I

It is the responsi.bi.li.ty of the caller to free the memory associ.ated wi.th


the returned default prl.nter name.
e.g. pszstrl.ng = QueryDefaultpri.nter():

f ree ( pszstri ng ) ;

PCHAR pch /* CHAR poi.nter


ULONG ulLength /* profl.le strl.ng sl.ze
B00L fRet /* B00L return code
LONG IRetLen = OL /* returned length
PSZ pszprfstr = NULL /* profi.le stri.ng
PSZ pszprtName = NULL /* default pri.nter name

/* query name stri.ng sl.ze


fRet = PrfQueryprofl.les1.ze( HINI_PROFILE /* -INI fl.le handle
``PM_SP00LER„
/* -applicati.on name
' "PRINTER„ /* -key name
&ulLength /* -returned data length
n
I.f (fRet && ulLength!=0)
pszprfstr = malloc((SHORT)ulLength): /* allocate memory for strl.ng */

1.f (pszprfstr!=NULL) /* query default pri.nte


1RetLen = PrfQueryprofl.1estri.ng( HINI_PROFILE /* -INI fl.1e handle
"PM_SP00LER'. /* -applicati.on name
"PRINTER" /* -key name
"" /* -default stri.ng
pszprfstr /* -returned stri.ng
ulLength /* -max stri.ng length
);

i.f (lRetLen!=0) /* I.f stri.ng returned */


(
/* fl.nd stri.ng end */
pch = strchr(pszprfstr, . ; ' ) ;
i.f (pch!=NULL && pch!=pszprfstr) /* i.f name exi.sts */
(
/* set name poi.nter */
pszprtName = pszprfstr;
*pch -'\0': /* null termi.nate strl.ng */
)
)

1.f (pszprtName==NULL) /* if error


f ree ( pszp rfstr ) : /* free memory

return ( pszprtName ) ;

Figure 12.4 QueryDefaultl}rinter Function.


PRINTINC; 237

qprtnams.c */
0 u e r y P r 1. n t e r N a in e s ( V 0 I D )

Return the pri.nter names.

returns: PSZ Pri.nter names or NULL (error or none found).


Note that each name l.s null terml.nated with the fl.nal name
termi.nated by two nulls.

It i.s the responsi.bi.li.ty of the caller to free the memory associ.ated wi.th
the returned pri.nter names.
e.g. pszstri.ng = Querypri.nterNames();

f r e e ( p s z S t r i. n g ) ;

ULONG ulLength /* profi.le strl.ng si.ze


B00L fRet /* B00L return code
ULONG ulRetLen = OL /* returned length
PSZ pszprfstr = NULL /* profl.le strl.ng
PSZ pszprtNames = NULL /* pri.nter names

/* query name strl.ng sl.Ze


fRet = PrfQueryprofl.les1.ze( HINI_PROFILE /* -INI fi.1e handle
"PM_SP00LER_PRINTER" /* -appll.catl.on name

NULL /* -key name


&ulLength /* -returned data length
in

i.f (fRet && ulLength!=0)


pszprfstr = malloc((SHORT)ulLength): /* allocate memory for stri.ng */

1.f (pszprfstr!=NULL) /* query pri.nter names


ulRetLen = PrfQueryprofl.1estrl.ng( HINI_PROFILE /* -INI fl.1e handle
"PM_SP00LER_PRINTER" /* -appl. name

NULL /* -key name


.`.. /* -default stri.ng

pszprfstr /* -returned strl.ng


ulLength /* -max strl.ng length
in

I.f (ulRetLen!=0 && *pszprfstr!='\0') /* 1.f fl.rst name exl.sts */


pszprtNames = pszprfstr; /* set prl.nter names pol.nter*/

1.f (pszprtNames==NULL) /* 1.f error


f ree( pszprfstr ) ; /* free memory

return ( pszprtNames ) ;

Figure 12.5 QuerylhinterNames Function.


238 OS/2 PRESENTATION MANAGER GPI

/* qprtinfo.c */
PSZ Querypri.nterlnfo( PSZ pszprtName
PSZ FAR* pszDefQ
PSZ FAR* pszDefDrv
PSZ FAR* pszDefDev
PSZ FAR* pszAddlQs
PSZ FAR* pszAdDrvDvs

/* Query the prl.nter port, default queue, default drl.ver and devl.ce name and
/* additl.onal queue and dri.ver.devi.ce names
/*
/* i.nputs: pszprtName Pri.nter name (e.g. PRINTER1).
/*

;: outputs: :!§Z::{§rv ::::::: i::::e:ag:I.;:+g(el:TLeA;ERjET) or NULL.


/* *pszDefDev Default devi.ce name (e.g. HP Laserjet Plus) or NULL
/* *pszAddlQs Addl.tl.onal queues (e.g. LPT2Q,LPT3Q) or NULL.
/* *pszAdDrvDvs Addi.ti.onal dri.ver.devi.ce names or NULL.
/*
/* returns: PSZ port name (e.g. LPT1) or NULL (for error)
/*
/* It I.s the responsibl.li.ty of the caller to free the memory associated wl.th
/* the returned port name.
/* e.g. pszstrl.ng = Querypri.nterlnfo(..);
/*.
/* f r e e ( p s z S t r i. n g ) :

PCHAR pch /* CHAR poi.nter


ULONG ulLength /* profi.le stri.ng sl.ze
B00L fRet /* B00L return code
PSZ pszstart /* stri.ng start
LONG IRetLen /* returned length
PSZ pszprfstr /* profi.le stri.ng
PSZ pszport /* port name
PSZ pszDefDrvLcl /* default drl.ver name
PSZ pszDefQLcl /* default queue name
PSZ pszAddlQSLcl /* addi.ti.onal queue names
PSZ pszAdDrvDvsLcl /* addi.ti.onal dri.ver.devi.ces
PSZ pszDefDevLcl /* default devi.ce name

/* query stri.ng si.ze


fRet = Prfoueryprofi.lesi.ze( HINI_PROFILE /* -INI fi.1e handle
"PM_SP00LER_PRINTER'. /* -applicati.on name

pszprtName /* -key name


&ulLength /* -returned data length
in

if (fRet && ulLength!=0)


pszprfstr = mal loc( (SHORT)ul Length) : /* allocate memory for stri.ng */

/* query prl.nter 1.nfo


lRetLen = PrfQueryprofi.lestri.ng( HINI_PROFILE /* -INI file handle
"PM_SP00LER_PRINTER.. /* -appli.cati.on name

pszprtName
``.. /* -key-default
/* name strl.ng

pszprfstr /* -returned strl.ng


ulLength /* -max strl.ng length

Figure 12.6 Querynrinterlnfo Function.


PRINTING

l.f (1RetLen!=0) /* 1.f stri.ng returned


(

I ************************************************************************** I
/**/
/* Now break the stri.ng i.nto three null terml.nated stri.ngs: */
/* port name */
/* dri.ver.devl.ce_names (begl.nnl.ng wl.th default drl.ver) */
/* queue_names (begl.nnl.ng wl.th default queue) */
/* (i.gnore the network parameters) */
/**/
/ ************************************************************************** 1

pszstart = pszprfstr; /* i.ni.ti.all.ze poi.nter


pch = strchr(pszstart ,I:.): /* fi.nd port name end
I.f (pch==NULL || pch==pszstart) /* I.f no name exi.sts
(
f ree( pszprfstr ) ; /* free the memory */
return ( NU LL ) ; /* return NULL */
)
pszport = pszstart:
*pch -'\0'; /* null terml.nate stri.ng */

i.niti.alize pointer */
pszstart = ++pch;
pch = strchr(pszstart, I ; ' ) ; fi.nd clef dri.ver name end */
l.f (pch==NULL I I pch==pszstart) I.f no name exi.sts */
(
f ree( pszprfstr ) : f ree the memory */
return ( NU LL ) ; return NULL */
)
*pch -'\0': /* null termi.nate strl.ng */
/* set clef drl.ver name */
pszDefDrvLcl = pszstart;

pszstart = ++pch; /* l.nl.tl.all.ze poi.nter


pch = strchr(pszstart, ' : ' ) ; /* fl.nd clef queue name end
I.f (pch==NULL) /* 1.f error
(
f ree( pszprfstr ) : /* free the memory */
return( NULL) ; /* return NULL */
)
*pch -'\0'; /* null termi.nate stri.ng */
i.f (pch!=pszstart) /* i.f name exi.sts */
/* set queue name */
pszDefQLcl = pszstart:

/ ************************************************************************** /
/**/
/* now break the queue_name stri.ng i.nto two null terml.nated strl.ngs: */
/* default queue_name */
/* addi.tional queue_names */
/**/
/ ************************************************************************** /

pszstart = pszDefQLcl ; /* I.ni.tl.all.ze pol.nter


pch = strchr(pszstart, I , I ) /* fi.nd ','separator
I.f (pch!=NULL) /* i.f separator exi.sts
(
*pch -'\0'; /* null termi.nate strl.ng
pszAddlQSLcl = ++pch; /* set addl queue names
)

Figure 12.6 (co71£j7}zJecz)


240 OS/2 PRESENTATION MANAGER GPI

I ************************************************************************** I
/**/
/* now break the default drl.ver.device_name strl.ng into two null */
/* termi.nated strl.ngs: */
/* default drl.ver.devi.ce_name */
/* addi.ti.onal dri.ver.devi.ce_names */
/**/
1 ************************************************************************** I

i;:::::::#ii::::::t,l, : , ,: ;: #!:::l;::::::i:::s
(

;i:*d;r;::;ici = ++pch; ;: :::]a::ri::i:e;t:i#:s :(


)

1************************************************************************** I
/**/
/* now break the default dri.ver.devl.ce_name strl.ng i.nto two null */

(: termi.nated s:::::it dri.ver_name :(


/* default device_name (or NULL l.f none) */
/**/
1 ************************************************************************** I

/* initi.all.ze pointer */
pszstart = pszDefDrvLcl */
ch = strchr(pszstart, ' . I ) /* find .,'separator
/* i.f separator exi.sts */
f (pch!=NULL)

*pch -'\0', /* null termi.nate stri.ng */


/* set clef devi.ce name */
pszDefDevLcl = ++pch;
)
)
if (pszDefDrv!=NULL)
*pszDefDrv = pszDefDrvLcl ; /* set return default dri.ver name
I.f (pszDefQ!=NULL)
*pszDefQ = pszDefQLcl : /* set return default queue name
I.f (pszAddlQs!=NULL)
*pszAddlQs = pszAddlQSLcl ; /* set return addl queue names
I.f (pszAdDrvDvs!=NULL)
*pszAdDrvDvs = pszAdDrvDvsLcl /* set return addl drl.ver.device names */
I.f (pszDefDev!=NULL)
*pszDefDev = pszDefDevLcl ; /* set return default devi.ce name */

return(pszport) :

Figure 12.6 (co7}££7iL4ecz)


PRINTING 2AI

/* postdevm.c */
B00L PostDevi.ceModes( HAB hab
PDRIVDATA FAR* pdri.vDataRet
PSZ pszDri.ver
PSZ pszDevi.ce
PSZ pszprl.nter
)
(
/* Return the DRIVDATA structure for the specl.fied drl.ver, devi.ce and
/* pri.nter using DevpostDevi.ceModes.
/*
/* l.nputs: hab Anchor block handle
/* pszDrl.ver Dri.ver name
/* pszDevl.ce Devl.ce name
/* pszpri.nter Pri.nter name
/*
/* outputs: pdrl.vDataRet DRIVDATA structure
/*
/* It i.s the responsi.bi.11.ty of the caller to free the memory associ.ated wi.th
/* the returned DRIVDATA structure.
/* e.g. fRet = PostDevl.ceModes(..&pdrl.vData..):
/*.
/* free(pdrl.vData);

LONG 1 Length /* DRIVDATA length


B00L fRet = FALSE /* B00L return code
PDRIVDATA pdrl.vData = NULL /* DRIVDATA poi.nter

*pdri.vDataRet = NULL;
/* i.nl.tl.all.ze DRIVDATA poi.nter*/

/* post devl.ce modes


1Length = DevpostDevl.ceModes( hab /* -anchor block handle
NULL /* -DRIVDATA poi.nter
pszDri.ver /* -dri.ver name
pszDevi.ce /* -devi.ce name
pszpri.nter /* -pri.nter name
DPDM_CHANGEPROP /* -Optl'Ons
in

l.f (1Length!=DPDM_ERROR && 1Length!=DPDM_NONE)


pdrl.vData = malloc((SHORT)1Length); /* allocate DRIVDATA memory */

1.f (pdri.vData!=NULL) /* query default prl.nter name


fRet = DevpostDevl.ceModes( hab /* -anchor block handle
pdri.vData /* -DRIVDATA poi.nter
pszDri.ver /* -dri.ver name
pszDevi.ce /* -devl.ce name
pszpri.nter /* -prl.nter name
DPDM_CHANGEPROP /* -Optl.Ons
) != DPDM_ERROR;

l`f (fRet) /* if no error


*pdrl.vDataRet = pdrl.vData;
/* set returned PDRIVDATA
else /* else
f ree ( pd ri vData ) ; /* free memory

return ( fRet ) :

Figure 12.7 PostDeviceModes Function.


242 OS/2 PRESENTATION MANAGER GPI

qdefqueu.c */
QueryDefa ul toueue ( V0 I D )

Return the default pri.nter queue name.

returns: PSZ Default pri.nter queue name or NULL (error or not found).
Thi.s functi.on null termi.nates the stri.ng (removi.ng .;').

It i.s the responsi.bi.1i.ty of the caller to free the memory assocl.ated wi.th
the returned default queue name.
e.g. pszstri.ng = OueryDefaultQueue():

f r e e ( p s z S t r i. n g ) ;

PCHAR pch /* CHAR pol.nter


ULONG ulLength /* profi.1e stri.ng si.ze
B00L fRet /* B00L return code
LONG IRetLen = OL /* returned length
PSZ pszprfstr = NULL /* profl.le strl.ng
PSZ pszQName = NULL /* default queue name

/* query name strl.ng sl.ze


fRet = PrfQueryprofl.les1.ze( HINI_PROFILE /* -INI fi.le handle
' ``PM_SP00LER„ /* -appli.cati.on name
"QUEUE,,
/* -key name
&ulLength /* -returned data length
in

1.f (fRet && ulLength!=0)


pszprfstr = malloc((SHORT)ulLength): /* allocate memory for strl.ng */

l.f (pszprfstr!=NULL) /* query default queue name


lRetLen = PrfQueryprofl.1estrl.ng( HINI_PROFILE /* -INI fi.1e handle
.`PM_SP00LER„
/* -appll.catl.on name
"QUEUE" /* -key name
``,, /* -default stri.ng
-returned strl.ng
pszprfstr /*
ulLength /* -max stri.ng length
in
I.f (1RetLen!=0) /* I.f stri.ng returned */
(
/* fl.nd strl.ng end */
pch = strchr(pszprfstr, ' ; ' ) ;
l.f (pch!=NULL && pch!=pszprfstr) /* i.f name exl.sts */
(
/* set name pol.nter */
pszQName = pszprfstr;
*pch -'\0'; /* null termi.nate stri.ng */
)
)

l.f (pszQName==NULL) /* I.f error


f ree( pszprfstr ) ; /* free memory

return ( pszQName ) ;

Figure 12.8 QueryDefaultQueue Function.


PRI NTI NC 243

qqnames.c */
Que ryQueueNames ( V0 I D )

Return the pri.nt queue names.

returns: PSZ Pri.nt queue names or NULL (error or none found).


Note that each name l.s null termi.nated wl.th the fi.nal name
termi.nated by two nulls.

It 1.s the responsi.bl.11.ty of the caller to free the memory associ.ated wi.th
the returned queue names.
e.g. pszstrl.ng = QueryQueueNames():

f r e e ( p s z S t r 1. n g ) ;

ULONG ulLength /* profl.1e strl.ng sl.ze


B00L fRet /* B00L return code
LONG IRetLen = OL /* returned length
PSZ pszprfstr = NULL /* profl.le stri.ng
PSZ pszQNames = NULL /* queue names

/* query name string size


fRet = PrfQueryprofl.1es1.ze( HINI_PROFILE /* -INI fi.1e handle
"PM_SP00LER_QUEUE" /* -appli.cati.on name

NULL /* -key name


&ulLength /* -returned data length
n
1.f (fRet && ulLength!=0)
pszprfstr = malloc((SHORT)ulLength); /* allocate memory for stri.ng */

I.f (pszprfstr!=NULL) /* query prl.nter names


1RetLen = PrfQueryprofl.1estri.ng( HINI_PROFILE /* -INI fl.1e handle
"PM_SP00LER_QUEUE" /* -appl. name

NULL /* -key name


``'' /* -default stri.ng

pszprfstr /* -returned strl.ng


ulLength /* -max strl.ng length
in

I.f (lRetLen!=0 && *pszprfstr!='\0') /* i.f fl.rst name exi.sts */


pszQNames = pszprfstr; /* set queue names pol.nter */

l.f (pszQNames==NULL) /* I.f error


f ree( pszprfstr ) ; /* freememory

return ( pszONames ) :

Figure 12.9 QueryQueueNames Function.


244 OS/2 PRESENTATION MANAGER GPI

qqdri.ver.c */
QueryQueueDrl.ver(PSZ pszQueue, PSZ FAR* pszDevl.ce)

Return the name of the default dri.ver for the speci.fl.ed queue.

1.nputs: pszQueue Queue name.

outputs: pszDevi.ce Devi.ce name.

returns: PSZ Drl.ver name or NULL (error or not found).


Thl.s functl.on null terml.nates the strl.ng removl.ng the '.I or I;I

It i.s the responsi.bi.1i.ty of the caller to free the memory associ.ated wi.th
the returned default prl.nter name.
e.g. pszstri.ng = QueryQueueDri.ver(..);

f r e e ( p s z S t r i. n g ) ;

PCHAR pch /* CHAR poi.nter


ULONG ulLength /* profi.le stri.ng si.ze
B00L fRet /* B00L return code
LONG IRetLen = OL /* returned length
PSZ pszprfstr = NULL /* profl.le strl.ng
PSZ pszDri.ver = NULL /* drl.ver name

*pszDevi.ce = NULL;
/* I.ni.ti.all.ze devi.ce poi.nter */

/* query name stri.ng si.ze


fRet = PrfQueryprofl.les1.ze( HINI_PROFILE /* -INI fi.1e handle
"PM_SP00LER_QUEUE_DD.'/* -appli.catl.on name

pszQueue /* -key name


&ulLength /* -returned data length
in

l.f (fRet && ulLength!=0)


pszprfstr = malloc((SHORT)ulLength); /* allocate memory for strl.ng */

1.f (pszprfstr!=NULL) /* query default drl.ver name


lRetLen = PrfQueryprofi.lestri.ng( HINI_PROFILE /* -INI fi.1e handle
"PM_SP00LER_QUEUE_DD" /* -app. name

pszQueue
..'. /* /*
-key name stri.ng
-default

pszprfstr /* -returned stri.ng


ulLength /* -max strl.ng length
):
1.f (lRetLen!=0) /* i.f strl.ng returned */
(
pch = strchr(pszprfstr, ' : ' ) : /* fl.nd stri.ng end */
l.f (pch!=NULL && pch!=pszprfstr) /* 1.f drl.ver name exists */
(

pszDri.ver = pszprfstr: /* set dri.ver name poi.nter */


*pch -'\0'; /* null termi.nate stri.ng */
ch = strchr(pszprfstr, ' . ' ) /* fi.nd stri.ng end */
f (pch!=NULL) /* 1.f devl.ce exi.sts */

*pch -'\0': /* null terml.nate strl.ng*/


*pszDevi.ce = ++pch: /* set devl.ce pol.nter */

Figure 12.10 QueryQueueDriver Function.


PRINTING

i.f (pszDri.ver==NULL) /* 1.f error


f ree( pszprfstr ) ; /* free memory

r e t u r n ( p s z D r 1. v e r ) ;

Figure 12.10 (con£ZnL4ed)

/* qqdri.vda.c */
PDRIVDATA QueryQDrl.verData(PSZ pszQueue)
(
/* Return the DRIVDATA structure for the default dri.ver of the specl.fl.ed
/* queue.
/*
/* l.nputs: pszQueue Queue name.
/*
/* returns: PDRIVDATA pol.nter to DRIVDATA structure or NULL (error or none).
/*
/* It I.s the responsi.bi.1i.ty of the caller to free the memory associ.ated wi.th
/* the returned DRIVDATA structure.
/* e.g. pdrl.vData = QueryQDri.verData(..):
/*.
/* f r e e ( p d r i. v D a t a ) ;

ULONG ul Length /* profi.le stri.ng si.ze


B00L fRet /* B00L return code
LONG IRetLen = OL /* returned length
PDRIVDATA pdri.vData = NULL /* DRIVDATA structure

/* query strl.ng si.ze


fRet = Prfoueryprofi.1esi.ze( HINI_PROFILE /* -INI file handle
"PM_SP00LER_QUEUE_DDDATA''/* -appli.cati.on name

pszQueue /* -key name


&ulLength /* -returned data length
in

1.f (fRet && ulLength!=0)


pdrl.vData = malloc((SHORT)ulLength): /* allocate memory for stri.ng */

I.f (pdrivData!=NULL) /* query DRIVDATA structure


1RetLen = PrfQueryprofi.lestrl.ng( HINI_PROFILE /* -INI fi.1e handle
"PM_SP00LER_QUEUE_DDDATA" /* -app.

pszQueue
.`'. /* /*
-key name stri.ng
-default

pdrl.vData /* -returned strl.ng


ulLength /* -max stri.ng length
in
1.f (lRetLen==0) /* i.f no strl.ng returned */
(
f ree( pdri vData ) ; /* free memory */
pdri.vData = NULL; /* set return value = NULL */
)

return ( pdri vData ) ;

Figure 12.11 QueryQDriverData Function.


246 OS/2 PRESENTATION MANAGER GPI

/* postjobp.c */
VOID PostiJobproperti.es( HAB hab
PDRIVDATA pdri.vData
PSZ pszDri.ver
PSZ pszDevl.ce

(
/* Post a Job Propertl.es dl.alog and return the suppll.ed DRIVDATA structure
/* modi.fi.ed by the end user selecti.ons. Note that thi.s method of usi.ng
/* DevpostDevi.ceModes may not be supported by all drl.vers. If an error 1.s
/* logged i.t can be i.gnored and i.s reset by thi.s functl.on before returni.ng
/* The ori.gi.nal DRIVDATA structure can sti.ll be used unmodi.fi.ed.
/*
/* i.nputs: hab Anchor block handle
/* pszDri.ver Dri.ver name
/* pszDevice Devl.ce name
/* pdri.vData DRIVDATA structure
/*
/* outputs: pdri.vData DRIVDATA structure modi.fi.ed by end user
/*

/* post devi.ce modes


DevpostDevi.ceModes( hab /* -anchor block handle
pdri.vData /* -DRIVDATA poi.nter
pszDrl.ver /* -dri.ver name
pszDevi.ce /* -devi.ce name
NULL /* -pri.nter name
DPDM_POSTJ0BPROP /* -Optl'Ons
in

W i. n G e t L a s t E r r o r ( h a b ) ; /* reset error (1..e. i.gnore l.t l.f */


/* not supported by thl.s dri.ver) */

return :

Figure 12.12 PostJobnroperties Function.


PRINTI NG 24]

/* prtdefpr.c */
B00L Pri.ntDefpri.nter(HAB hab)
(
/* Pri.nt Gpl. graphi.cs to the default pri.nter. */

.`Prl.nt Job"
#defi.ne PDOCNAME
#defi.ne PDOCNAMELEN ( LONG ) s 1. zeof ( PDOC NAM E )
"Hello World"
#defi.ne PRINTTEXTP
#defi.ne PRINTTEXTPLEN ( LONG ) ( s I. zeof ( PRI NTTEXTP ) -1 )

PSZ pszpri.nter /* default pri.nter


PSZ pszDefQ /* default pri.nter queue
PSZ pszDefDrv /* default prl.nter drl.ver name
PSZ pszDefDev /* default pri.nter devl.ce name
PDRIVDATA pdrl.vData /* pol.nter to DRIVDATA structure
DEVOPENSTRUC dopData /* DEVOPENSTRUC structure
SIZEL S1.zl /* PS sl'ze
P0INTL ptlpo,'nt /* coordi.mate pol.nt
LONG i Length /* length
USHORT usJobld /* job l'd
PSZ pszport = NULL /* port name
HDC hdc = DEV_ERROR /* DC handle
B00L fRetA = FALSE /* B00L return code
B00L f Ret = FALSE /* B00L return code
HPS hps = GPI ERROR /* PS handle

pszpri.nter= QueryDefaultpri.nter(); /* query default pri.nter name

i.f (pszprl.nter!=NULL); /* Query port, queue, drl.ver and devi.ce


pszport= Queryprl.nterlnfo( pszprl.nter /* -pri.nter name
&pszDefQ /* -returned queue name address
&pszDefDrv /* -returned drl.ver name address
&pszDefDev /* -returned devi.ce name address
NULL /* -addi.ti.onal queues
NULL /* -addl dri.ver.devi.ce names
in

1.f (pszport!=NULL); /* post devi.ce modes


fRet = PostDevl.ceModes( hab /* -anchor block handle
&pdri.vData /* -DRIVDATA
pszDefDrv /* -dri.ver name
pszDefDev /* -device name
pszpri.nter /* -prl.nter name
n
/* set DevopenDC params
dopData . ps z LogAdd res s pszDefQ: /* -logl.cal address
d o p D a t a . p s z D r 1. v e r N a in e pszDefDrv ; /* -dri.ver name
d o p D a t a . p d r i. v p" Pd M_CLS
r i. v D aTtDa '.; /* -DRIVDATA
dopData . pszDataType /* -data type
"Gpi. Pri.ntl.ng''; /* -comment
dopData . pszcomment
dopData . pszQueueprocName NULL; /* -queue proc name (default)
"COL=C XFM=0":/* -queue proc params
dopData . pszQueueprocpa rams
dopData . pszSpool erpa rams NULL: /* -spooler params
dopData . pszNetworkpa rams NULL; /* -network params (not used)

Figure 12.13 I}rintDefp]rinter Function.


248 OS/2 PRESENTATION MANAGER GPI

1.f (fRet) /* open an OD_QUEUED DC


hdc = DevopenDC( hab /* -anchor block handle
OD_QUEUED /* -DC type
* ,, /* -token
9L /* -number of data elements
(PDEVOPENDATA)&dopData /* -open DC data
NULL /* -compati.ble DC handle
in

f r e e ( p s z P r I. n t e r ) ;
f ree ( pszport ) ;
f r e e ( p d r i. v D a t a ) ;

sl.zl .cx = 10000L;


sl.zl .cy = 10000L;
1. f ( hd c ! =D EV_E RRO R ) /* create PS
hps = Gpi.Createps( hab /* -anchor block handle
.hdc /* -DC handle
& s 1' z 1 /* -PS sl'ze
PU ARBITRARY /* Opt,.Ons
G P I F_D E FAU LT
GPIA_NOASSOC
G P I T_N 0 RNA L
in

1.f (hps!=GPI_ERROR) /* associate PS and DC


fRetA = Gpl.Associ.ate(hps, hdc);

lLength -OL:
l.f (fRetA) /* i.ssue start document DevEscape
fRet = DevEscape( hdc /* -DC handle
DEVESC_STARTDOC /* -escape code
PDOCNAMELEN /* -sl.ze of document name
PDOCNAME /* -null terml.nated document name
&1Length /* -si.ze of output data (OL)
NULL /* -output data (not used
) --DEV_OK;
else
fRet = FALSE:

Pol'nt.x -1000L:
Pol'nt.y -1000L:
/* draw to the prl.nter */
fRet = (B00L)Gpi.Charstri.ngAt( hps
' &ptlpol'nt
PRINTTEXTPLEN
PRINTTEXTP
in
1 Length 2L;
1` f ( f R e t ) /* i.ssue end document DevEscape
f Ret = DevEscape( hdc /* ~DC handle
DEVESC_ENDDOC /* -escape code
OL /* -length of i.nput data (OL)
NULL /* -I.nput data (not used)
&lLength /* -si.ze of output data (2L)
(PBYTE)&usJobld /* -output data (returned job 1.d
) --DEV_OK;

Figure 12.13 (co7i££rizted)


PRINTING 249

1. f ( f R e t A )
fRet = Gpi.Associ.ate(hps, NULL) && fRet; /* di.ssoci.ate PS and DC

I. f ( hps ! =GP I_ERROR )


fRet = Gpl.Destroyps(hps) && fRet; /* destroy PS

I. f ( hd c ! =D EV_E RRO R )
fRet = DevcloseDC(hdc) != DEV_ERROR && fRet: /* close DC

return ( fRet ) ;

Figure 12.13 (confinL4edJ

prtdefqu.c */
L Prl.ntDefQueue(HAB hab, ULONG ulpostD1.alog)

Pri.nt Gpi graphi.cs to the default pri.nt queue. Opti.onally post a


propertl.es di.alog.

i.nputs: hab Anchor block handle


ulpostDi.alog Optl.ons : (0) Do not post Job Propertl.es Di.alog
(1) Post Job Properti.es Di.alog

Note that not all dri.vers support a Job Properti.es D1.alog l.n thi.s mode.

#defl.ne QDOCNAME "Pri.nt Job"


#defi.ne QDOCNAMELEN (LONG)si.zeof(ODOCNAME)
#defi.ne PRINTTEXTQ "Hello world..
#defl.ne PRINTTEXTQLEN (LONG)(sl.zeof(PRINTTEXTQ)-1)

PDRIVDATA pdri.vData = NULL /* poi.nter to DRIVDATA structure


PSZ pszDevi.ce /* devi.ce name
DEVOPENSTRUC dopData /* DEVOPENSTRUC structure
SIZEL s l' Z 1 /* PS sl'ze
P0INTL p t 1 P 0 1' n t /* coordi.nate pol.nt
LONG 1 Length /* length
USHORT u s lJ o b I d /* returned job i.d
PSZ pszQueue NULL /* queue name
PSZ p s z D r 1. v e r NULL /* dri.ver name
HDC hdc DEV_ERROR /* DC handle
B00L fRetA FALSE /* B00L return code
B00L fRet FALSE /* B00L return code
LONG lRet DPDM_ERROR /* LONG return code
HPS hps = GPI ERROR /* PS handle

pszoueue= QueryDefaultQueue(): /* query default queue name

Figure 12.14 HintDefQueue Function.


250 OS/2 PRESENTATION MANAGER GPI

1.f (pszQueue!=NULL) /* query drl.ver and devi.ce names


pszDrl.ver = QueryQueueDrl.ver( pszQueue /* -queue name
&pszDevi.ce /* -devi.ce name
in
1.f (pszDri.ver!=NULL)
pdrl.vData = QueryQDriverData(pszQueue): /* query DRIVDATA

if (pdri.vData!=NULL)
(
lRet = DEV_OK;
/* Post Job Propertl.es Di.alog
i.f (ulpostD1.alog) /* this opti.on i.s requested
lRet = DevpostDevl.ceModes( hab /* -anchor block handle
pdri.vData /* -DRIVDATA pointer
pszDri.ver /* -dri.ver name
pszDevi.ce /* -devl.ce name
NULL /* -prl.nter name
DPDM_POSTJ0BPROP/* -opti.ons
);
)
/* set DevopenDC params
dopData . psz LogAdd ress pszQueue; /* -1ogl.cal address
d o p D a t a . p s z D r I. v e r N a in e pszDri.ver; /* -drl.ver name
d o p D a t a . p d r 1. v P dri.vData; /* -DRIVDATA
dopData . pszDataType PM_CLSTD'': /* -data type
dopData.pszcomment = "Gpl. Pri.nting'';/* -comment
dopData.pszQueueprocName = NULL: /* -queue proc name (default)
dopData.pszQueueprocparams ="COL=C XFM=O /* -queue proc params
dopData.pszSpoolerparams = NULL; /* -spooler params
dopData.pszNetworkparams = NULL; /* -network params (not used)

i.f (lRet!=DPDM_ERROR) /* open an OD_QUEUED DC


hdc = DevopenDC( hab /* -anchor block handle
OD_OUEUED /* -DC type
I * ,,
/* -token
.9L /* -number of data elements
(PDEVOPENDATA)&dopData /* -open DC data
NULL /* -compati.ble DC handle
);

f ree ( pszQueue ) ;
f r e e ( p s z D r 1. v e r ) ;
f r e e ( p d r 1. v D a t a ) :

sizl .cx = 10000L:


sl'zl .cy -10000L:
I. f ( hd c ! =D EV_E RRO R ) /* create PS
hps = Gpl.Createps( hab /* -anchor block handle
.hdc /* -DC handle
& s 1' Z I /* -PS sl'Ze
P U_A RB I T RA RY /* Optl'Ons
G P I F_D E FAU LT
G P I A_N 0 A S S 0 C
G P I T_N 0 RNA L
in

if (hps!=GPI_ERROR)
fRetA = Gpi.Assocl.ate(hps, hdc): /* associate PS and DC */

Figure 12.14 (con££7?Lied)


PRINTING 251

nt.x
nt.y

l'f (fRetA) /* 1.ssue start document DevEscape


fRet = DevEscape( hdc /* -DC handle
DEVESC_STARTDOC /* -escape code
QDOCNAMELEN /* -si.ze of document name
QDOCNAME /* -null termi.nated document name
&lLength /* -sl.ze of output data (OL)
NULL /* -output data (not used
) --DEV_OK;
l'f (fRet) /* draw to the pri.nter
fRet = (B00L)Gpl.Charstrl.ngAt( hps
&ptlpo,.nt
PRINTTEXTQLEN
PRINTTEXTQ
in
1 Length 2L:
1' f ( f R e t ) I.ssue end document DevEscape
fRet = DevEscape( hdc -DC handle
DEVESC_ENDDOC -escape code
OL
-length of i.nput data (OL)
NULL 1.nput data (not used)
&lLength si.ze of output data (
(PBYTE)&usJobld output data (returned
) --DEV_OK;

1. f ( f R e t A )
fRet = Gpi.Associ.ate(hps, NULL) && fRet; /* di.ssoci.ate PS and DC

I. f ( h p s ! = G P I _ E R R 0 R )
fRet = Gpi.Destroyps(hps) && fRet; /* destroy PS

i. f ( h d c ! = D E V _ E R R 0 R )
fRet = DevcloseDC(hdc) != DEV_ERROR && fRet; /* close DC

return ( fRet ) ;

Figure 12.14 (co7}££nztecz)


252 OS/2 PRESENTATION MANAGER GPI

/* prl.ntraw.c */
B00L Prl.ntRawData(HAB hab)
(
/* Pri.nt raw data to the default prl.nter. */
``Prl.nt Job"
#defl.ne RDOCNAME
#define RDOCNAMELEN ( L 0 N G ) s 1. z e o f ( R D 0 C N A M E )
"Raw Data Raw Data Raw Data Raw Data Raw Data"
#defl.ne RAWDATA
Jfdefl.ne RAWDATALEN ( LONG ) s 1. zeof ( RAWDATA )

PSZ p s z P r 1. n t e r /* default pri.nter


PSZ pszDefQ /* default pri.nter queue
PSZ pszDefDrv /* default pri.nter dri.ver name
PSZ zDefDev /* default pri.nter devl.ce name
PDRIVDATA /* poi.nter to DRIVDATA structure
DEVOPENSTRUC pData /* DEVOPENSTRUC structure
LONG ength /* length
USHORT usJobld /* job 1.d
PSZ pszport = NULL /* port name
HDC hdc = DEV ERROR /* DC handle
B00L fRet = FALSE /* B00L return code

pszprl.nter= QueryDefaultprl.nter(): /* query prl.nter name

1.f (pszprinter!=NULL); /* query port, queue, drl.ver and devi.ce


pszport= Queryprl.nterlnfo( pszprl.nter /* -pri.nter name
&pszDefQ /* -returned queue name address
&pszDefDrv /* -returned dri.ver name address
&pszDefDev /* -returned devi.ce name address
NULL /* -addi.ti.onal queues
NULL /* -addl dri.ver.devi.ce names
):

l.f (pszport!=NULL); /* post devi.ce modes


fRet = PostDevi.ceModes( hab /* -anchor block handle
&pdrivData /* -DRIVDATA
pszDef Drv /* -dri.ver name
pszDefDev /* -devl.ce name
pszprl.nter /* -pri.nter name
in
/* set DevopenDC params
dopData . psz LogAdd ress pszDefQ; /* -1ogi.cal address
d o p D a t a . p s z D r I. v e r N a in e pszDefDrv : /* -dri.ver name
d o p D a t a . p d r i. v p d r 1. v D a t a ; /* -DRIVDATA
`` P M_Q_ RAW „
dopData . pszDataType /* -data type
"Raw Data"
dopData . pszcomment /* -comment
dopData . pszQueueprocName NULL; /* -queue proc name (default)
dopData . pszQueuep rocpa rams NULL; /* -queue proc params
dopData . pszSpool erpa rams NULL: /* -spooler params
dopData . pszNetworkparams NULL: /* -network params (not used)

l'f (fRet) /* open an OD_QUEUED DC


hdc = DevopenDC( hab /* -anchor block handle
OD_QUEUED /* -DC type
* ,, /* -token
9L /* -number of data elements
(PDEVOPENDATA)&dopData /* -open DC data
NULL /* -compatible DC handle
in

Figure 12.15 nrintRawData Function.


PRINTING 253

f r e e ( p s z P r 1. n t e r ) ; /* free pri.nter name memory */


free( pszport ) : /* free port name etc. memory */
f r e e ( p d r 1. v D a t a ) : /* free DRIVDATA memory */

lLength -OL;
l. f ( hd c ! =D EV_E RRO R ) /* i.ssue start document DevEscape
fRet = DevEscape( hdc /* -DC handle
DEVESC_STARTDOC /* -escape code
RDOCNAMELEN /* -si.ze of document name
RDOCNAME /* -null termi.nated document name
&lLength /* -sl.ze of output data (OL)
NULL /* -output data (not used
) --DEV_OK;
else
fRet = FALSE;

lLength -OL:
1' f ( f R e t ) /* i.ssue raw data DevEscape
fRet DevEscape( hdc /* -DC handle
DEVESC_RAWDATA /* -escape code
RAWDATALEN /* -length of raw data
RAWDATA /* -raw data
&lLength /* -si.ze of output data (OL)
NULL /* -output data (not used)
) --DEV_OK;

lLength = 2L;
1` f ( f R e t ) /* l.ssue end document DevEscape
fRet DevEscape( hdc /* -DC handle
DEVESC_ENDDOC /* -escape code
OL /* -length of i.nput data (OL)
NULL /* -i.nput data (not used)
&1Length /* -sl.ze of output data (2L)
(PBYTE)&usJobld /* -output data (returned job I.d
) --DEV_OK;

1. f ( h d c ! = D E V _ E R R 0 R )
fRet = DevcloseDC(hdc) != DEV_ERROR && fRet; /* close the DC */

return ( f Ret ) ;

Figure 12.15 (co7}££nttecz)


254 OS/2 PRESENTATION MANAGER GPI

qryqproc.c */
Que ryQueuep roces s ors ( V0 I D )

Return the pri.nt queue processor names.

returns: PSZ Prl.nt queue processor names or NULL (error or not found).
Note that each name l.s null termi.nated wl.th the fl.nal name
termi.nated by two nulls.

It i.s the responsi.bi.lity of the caller to free the memory associ.ated wi.th
the returned pri.nt queue processor names.
e.g. pszstri.ng = Oueryoueueprocessors();

free ( pszstri ng ) ;

ULONG ulLength /* profl.1e stri.ng sl.ze


B00L fRet /* B00L return code
LONG IRetLen = OL /* returned length
PSZ pszprfstr = NULL /* profl.le stri.ng
PSZ pszQprocs = NULL /* queue processor names

/* query queue stri.ng si.ze


fRet = PrfQueryprofl.1esl.ze( HINI_PROFILE /* -INI fi.1e handle
' ``PM_SP00LER_OP" /* -applicati.on name
NULL /* -key name
&ulLength /* -returned data length
in

if (fRet && ulLength!=0)


pszprfstr = mal 1 oc( (SHORT)ul Length) ; /* allocate memory for stri.ng */

I.f (pszprfstr!= NULL) /* query queue names


1RetLen = PrfQueryprofl.lestrl.ng( HINI_PROFILE /* -INI fl.le handle
"PM_SP00LER_QP" /* -appli.cati.on name

NULL /* -key name


"" /* -default stri.ng
pszprfstr /* -returned strl.ng
ulLength /* -max stri.ng length
in

l.f (1RetLen!=0 && *pszprfstr!='\0') /* i.f fi.rst name exi.sts */


pszQprocs = pszprfstr: /* set queue names poi.nter */

l.f (pszQprocs==NULL) /* I.f error


f ree( pszprfstr ) ; /* free memory

return ( pszQprocs ) :

Figure 12.16 QueryQueuel}rocessors Function.


The OS/2 2.0 32-Bit Operating System

IBM has made no secret of its intention of providing Osra Version 2.0, the 32-bit
version of the current operating system, and the IBMM4icrosoft Software Devel-
opment Kit (SDK) is already available. At the time of writing this book, much of
the content of OS# Version 2.0 is well established. Although is not possible to say
when this release will become available or what its exact content will be, with one
or two exceptions, it can be assumed that the nresentation Manager functions are
available (as described in this book) with the new 32-bit flat memory model API
discussed below. The only change for the majority of the GPI functions is a change
to the precise meaning of any pointers (this is frequently hidden by the compiler).
OSA version 2.0 proL|zidssLLa±inary comBa±ibls Apl for use witha±s]EzamJ
exisring 16-bit a licatio All program examples provided in this book should
Ore continue to operate successfully using the Version 2.0 16-bit API.
In addition, it provides a 32-bit flatmemory model API that hides the Segmen-

Of the Inte|TM
processor,provides improved portability, and eliminates the 64K addressing
limitations inherent in the segmented 16-bit memory model. Existing 16-bit
applications may be converted to the new 32-bit API by flattening any 16-bit
segment and offset operations and removing all `far' references. The application
must then be rebuilt using the new 32-bit language compiler and tools.
For the majority of the programs in this book, removal of `far' references,
recompilation, and so forth, is all that is required. For other functions (e.g., the
function DisplaypMError in chapter 1), segment and offset pointer operations
must be modified to conformi to the 32-bit flat memory model.
Although the 16-bit API provides binary compatibility for all existing I+esenta-
tion Manager functions, a few of these existing functions may not be available with
the 32-bit API, and some of these will be replaced by different (and better) 32-bit

255
256 OS/2 PRESENTATION MANAGER GPI

functions. All 16-bit API functions, however, continue to be available to 32-bit


Mixed Applications that elect to use both 32-bit and 16-bit Apls. The 32-bit API
also provides some new functions and a number of enhancements to the original
16-bit functions.
APPENDIX 1

DevopenDC Parameters

HDC PASCAL FAR DevopenDC( IIAB hab


LONG IType
PSZ pszToken
LONG ICount
PDEVOPENDATA pdopData
HDC hdccomp

);

nab
This is the anchor block handle returned by Winlnitialize.

IType

This is the DC type and is specified as one of:


OD_QUEUED;
OD_DIRECT,
OD_INFO;
OD_METAFILE;
OD_METAFILE_NOQUERY; and
OD MEMORY.

257
258 OS/2 PRESENTATION MANAGER GPI

pszToken
This is intended to identify the device information to be taken from the INI file
instead of from the pdopData parameter. This parameter is currently ignored and
should be specified as "*" indicating that no information should be taken from the
INI file.

lcount

This is the number of pdopData elements provided. For a DC type of OD REM-


ORY, this should be specified as zero. For other DC types, a value of up to nine can
be specified. Values less than nine cause the omitted elements to be defaulted.

pdopData
This provides a variable number of additional DevopenDC parameters. In theory,
not all the elements are required in all cases but it is normally safer to provide the
complete structure. For a DC type of OD_MEMORY, this should be specified as
NULL as the hdccomp parameter identifies the driver and, thus, provides all the
necessary information (see the note below for printers that support multiple
resolutions). Otherwise, this parameter can be viewed as either:
a pointer to a DEVOPENDATA structure
Or

an array of PSZ (null terminated string pointers) as defined by


PDEVOPENDATA where the third element is actually of type
PDRIVDATA and must be typecast to PSZ.
It is possible (using the lcount parameter above) to provide less
than the maximum number of structure/aITay elements, allowing
the remainder to be defaulted. In practice, however, as can be ob-
served from the examples in this book, it is normally safer to pro-
vide the complete structure.
The pdopData structure (array elements) are as follows:

pdopData.pszl.ogAddress ®dopData [ADDRESS])


For a DC of type OD_DIRECT, this is the logical device address or
port name (e.g., "LFT1", "COM1").
For a DC of type OD_QUEUED, this is the user specifiable queue
name (e.g., "LFTIQ", "COMIQ").
For a non-display DC of type OD_INFO, this is the logical device
address or port name (e.g., "LFT1'', "COM1").
For a display DC of type OD_INFO or for any other DC type, this
should be specified as NULL.
DEVOPEN DC PARAM ETERS Z5S

Port and queue names can be queried using PrfQueryHofilestr-


ing (see chapter 12).

pdopData. pszDriverName ®dopData [DRIVER_NAME])


For a DC of type OD_DIRECT, OD_QUEUED, or OD INFO for a
non-display device, this is the name of the presentation-driver for
which the DC is required (e.g., "IBM4019", "IIASERJET"). The coITe-
sponding driver (IBM4019.DRV, eke.) must be present in the path de-
fined for that driver at installation time (i.e., as specified in the INI
file).

For a DC type of OD_DIRECT for a display device, OD METAF-


ILE or OD METAFILE_NO_QUERY, this should be specified as
"DISPLAY;.

Driver names can be queried using HrfQueryl}rofilestring, which


may return the driver name as the first part of a
drivemame.devicename string (see chapter 12).
pdopData.pdriv ®dopData [DRIVER_DATA])
For a DC of type OD_DIRECT, OD_QUEUED, or OD_INFO, this
is a pointer to a DRIVDATA structure. This may be specified in one
of four different ways:
1. For drivers without a dot qualified device name extension (e.g.,
IBM4019), this can be specified as NULL, although the altema-
tive methods below such as DevpostDeviceModes may be used
if appropriate. For drivers that do have a dot qualified device
name (e.g., PLOTI`ERS.IBM6180), one of the following methods
must be used.
2. A DRIVDATA structure specifying the device name may be
built, as shown in the example below, by the application.
However, this is not the recommended method as all printer and
job properties will be defaulted.
(
pdriv.cb= sizeof@RIVDATA);
pdriv.Iversion= OL;
strcpy®driv. szDeviceName, "IBM6180");
abGeneralData[0] = OxOO;
)
3. A DRIVDATA stnicture can be obtained using
DevpostDeviceModes. This method prompts the driver to use
printer device and job options (e.g., portrait/landscape) stored
previously in the INI file via the Hint Manager dialogs and
optionally allows these to be modified (and the INI file updated)
from DevpostDeviceModes end user dialogs.
4. A DRIVDATA structure can be built using FIfQueryHofilestr-
260 OS/2 PRESENTATION MANAGER GPI

ing (Application name = "PM_SPOOIHR_QUEUE_DDDATA"


Key name = Queue Name). This method uses printer job options
set previously using the printer queue I}rint Manager dialog.
These will oveITide options set using the printer name Hint
Manager dialog.
See chapter 12 for examples of the above. For other DC types, this
parameter can be specified as NULL or omitted. This includes DCs
of type OD_MEMORY but see the note below.
pdopData. DataType ®dopData H)ATA_TYPE])
For a DC of type OD_QUEUED (or a DC of type OD_DIRECT re-
quired to print a previously queued print file), this is the print file
data type and can be one of the following:
"PM_Q_STD" is the standard print spool file format that closely
resembles a MetaFile. This is the recolnlnended format and is the
default if this parameter is not specified. In this format, the print
file is fairly device independent but all system fonts required for
printing must be installed as public fonts on the local workstation
for local printing or on the print server for network printing.
The intention of this format is to provide a device independent for-
mat that enables printer' pooling using different printers. Although
this is theoretically possible, OSA is not currently enabled for this,
allowing only printer pooling using printers of the same type.
"PM_Q_RAW" is used for creating print files in device specific for-
mat. In this format, print files are generally unsuitable for printing
on devices other than that for which they were originally created (al-
though in fact they may often contain ASCII text with device spe-
cific escapes). The advantage of this format is that there is no re-
quirement for system fonts to be available anywhere other than on
the requesting process. Device fonts required for printing must, of
course, be installed on the target device. nrinter and job property di-
alog selections are generally ignored for PM_Q_RAW format.
Other Strings can be used to specify special formats unique to a
particular print queue processor.
For other DC types, or default, this parameter can be specified as
NULL or omitted.
pdopD ata.pszcomment ®dopData [COMMEN'I])
For a DC of type OD_QUEUED, this is an optional natural lan-
guage description of the job which, for a print ].ob, may be displayed
(using the Hint Manager) together with other job details when the
job is in the print queue. For a MetaFile DC, this description is
stored in the MetaFile.
DEVOPEN DC PARAM ETERS 261

For other DC types, this parameter can be specified as NUIIL or


omitted.
pdopData.pszQueuel+rocName ®dopData [PROC_NAME])
For a DC of type OD_QUEUED, this parameter is the name of the
print queue processor and should be defaulted for normal printing.
The default is defined (using I+int Manager setup) separately for
each queue and is normally "PMPRINT". For applications with no
special requirements (and that, for example, are printing using the
default queue), it should be possible to assume that the default
queue processor is suitable for normal printing. This enables alter-
native (compatible) queue processors to replace "PMPRINT" as a
queue default and remain transparent to the application. Alterma-
tively, for applications with special requirements, the name of the re-
quired queue processor (installed via the Control Panel) can be speci-
fied explicitly, or a queue with this queue processor selected as its
default can be used. For example, an application may wish to use a
special queue processor (e.g., PMPLOT) to perform. the reverse clip-
ping required for plotting.
The installed queue processor names can be queried using
HfQueryl}rofilestring (see chapter 12).
For other DC types, or default, this parameter can be specified as
NULL or omitted.
p dopD ata.pszQueuenrocparams ®dopData [PROC_RARAMS])
For a DC of type OD_QUEUED, this is an optional string of print
queue processor parameters of the fo]rm "keyword=value key-
word=value keyword=value", with the individual parameters sepa-
rated by spaces. Each queue processor may define its own require-
ments for this parameter. PMPRn`IT is the default Fkesentation
Manager print queue processor (see Appendix 2 for a description of
the PMPRINT queue processor parameters).
For other DC types or default, this parameter can be specified as
NIL or omitted.
pdopData.psz Spoolerparalns ®dopData [SPL_RARAMS])
For a DC of type OD_QUEUED, this is an optional string of
spooler queue manager parameters of the form. "keyword=value key-
word=value", with the individual parameters separated by spaces.
The valid keywords are `FORM=f,' and `PRTY=x.'
FORM=f specifies the name of a valid for.in (as returned by
DevQueryHardcopycaps). Note that the job will not actually print
unless the specified formi is installed or one that is selectable with-
out operator intervention. This should not be used if the
262 OS/2 PRESENTATION MANAGER GPI

DRIVER DATA field above contains a DRIVDATA stmcture re-


turned by DevpostDeviceModes as this includes a fo]rm. code.

PRTY=xx specifies the job priority in the range 00-99 ®ighest=99,


default=50).

For other DC types or default, this parameter can be specified as


NULL or omitted.

pdopData.pszNetworkparams ®dopData INETWORK_PARAMS])

This parameter is cuITently unused (even by IBM OSA Extended


Edition) and should therefore be specified as NULL or omitted.

hdc

Bitmaps are always owned by a particular device and, for a DC type of OD_MEM-
ORY, this is the handle of any existing DC of the device for which the OD REM-
ORY DC is required. An OD_MEMORY DC thus created, is suitable for u=e with
all DCs for the device, regardless of whether they are OD_QUEUED or OD DI-
RECT.
For DC types other than OD_MEMORY, this parameter should be NULL.
It was stated above that the pdopData (or DEVOPENPENDATA) paralneter
should be specified as NUIL when opening an OD_MEMORY DC. Although this
accurately reflects the API definition and works in the majority of cases, it does
require qualification. When drawing to a bitmap owned by a print driver that
supports a number of selectable resolutions (e.g., the IBM4019 driver supports
resolutions of 300, 150, loo, and 75 pels per inch), the driver is currently unable
to determine the correct resolution to use, and instead will use its own default. For
example, if the page units of the PS associated with the bitmap OD_MEMORY
memory DC are PU_LOENGLISH, a line 100 units long is drawn to the bitmap
and GpiBitBlt is used to output the bitmap to the printer, a line of one inch should
be printed. If the actual and driver default resolutions are the same, then the line
will be coITect. For example, if the default printer resolution is 150 and the actual
resolution is 300, then the length of the printed line will be halved; if the actual
resolution is 75, the length will be doubled. This problem does not apply when
working with device units (i.e., PU_PELS) or when performing straightforward
bitmap image operations. It is possible that this may eventually be corrected
intermally by changes to the drivers and device driver interface but presently, the
recommended bypass (for some drivers) is to supply a DEVOPENSTRUC param-
eter with a DRIVDATA structure providing the required resolution.
APPENDIX 2

PMPRINT Queue Processor Parameters

For a DC of type OD_QUEUED, this is an optional string of print queue processor


parameters of the forml "keyword=value keyword=value keyword=value". For
PMPRINT, the valid keywords are `COP=,' `ARE=,' `FIT=,' XFM=,' XIIT=,' and
`COL=.' Note that the `ARE=' and `FIT=' parameters operate on the page viewpoit
that reflects the PS page dimensions converted to device coordinates. They will
only, therefore, give correct results if the PS page dimensions (specified on
Gpicreateps) accurately reflect the correct fo]rm. size. This is not normally
achieved by defaulting the PS page dimensions. Note that the PS page dimensions
are less important if the `XFM=0' option is used.

COP=n
This specifies the number of copies n (n is an integer >=0).
ARE=
This specifies the size and position of the output area as follows:
ARE=C specifies that the required output area is maximum size
(i.e., equal to the size of maximum available output area) but does
not imply that the output is scaled to fill it.
ARE=w,h,I,t specifies the size and position of the required output
area (where w,h are width, height and I,t are left and top offsets of
the top left corner relative to the top left corner of the maximum
available output area, all expressed as integer percentages of the
maximum available output area). These are not particularly easy to
use but the example in Figure A2-1 should help to illustrate their
use. Other examples also appear in the IBM OSA nrogramming
Guide.

263
264 OS/2 PRESENTATION MANAGER GPI

I HaLxl- Output Area (Fom 9-iz®)

<-c->Hreq
<-'r®q - >
i:5::::ee8?tTut A-red
I

tb
•-.-,I 1
--------
center
I

CI 1p

lil

Real Size Output


(1n tbls caB® cllppod)

"FIT=1,t" wh®r® 1=a*100/Wr®.1, t=b*100/Hr®al

"AREEr,h, I, t" where t7Wreq*100/VDex, h=Hreq*100/IIDex

1=c*100/VDex, t-nd*100/Hda]t

Figure A2.1 Use of FIT= and ARE= Parameters

FIT=
This specifies the size and position of the actual output inside the
output area requested (using ARE=) as follows:
FIT=S specifies that the actual output (i.e., the PS page)
should be scaled to fit the required output area (i.e., drawn as
large as possible while retaining its aspect ratio such that a
circle remains a circle). At least one dimension of the picture
will completely fill the corresponding dimension of the required
output area while the other dimension will be centered where
applicable.

The `scale to fit' option may not provide the required results
in many cases (see below).
PMPRINT QUEUE PROCESSOR PARAMETERS Z65

FIT=l,t specifies that the picture should be printed real size


(i.e., not scaled) with its origin defined by I and t. These are the
offsets of the point in the real size output (or presentation page)
that is to appear at the center of the required output area
(defined by ARE=). The values are relative to the top left cormer
of, and are expressed as integer percentages of the real size
output (or presentation page) dimensions. These are not partic-
ularly easy to use but the example in Figure A2-1 should help
to illustrate their use. Other examples also appear in the IBM
OSG Erogramming Guide.
COL=
This specifies whether the picture should be output in color or
(where supported) in different shades of gray ("COL=C"), or whether
it should be output in monochrome ("COL=M") with only a single
foreground and background color.
XFM=
This specifies whether the output should be printed real size (i.e.,
as OD_DIRECT) ignoring the FIT= and ARE= parameters
("XFM=0"), or whether its position and size should be determ.ined
using the FIT= and ARE= parameters ("XFM=1") as described above.
XLT=
As explained in chapter 7, when the resolution of the output de-
vice is high compared to that of the PS page, (0,0) in world coordi-
mates will not transfo]rm to (0,0) on the device; typically it might
transfo]rm. to (1,1). This does not normally present a problem unless
a device happens to require every available pel in order to print a
row of tezit containing the maxilnum possible number of characters.
For such devices, this translation can cause the maximum number
of characters printed horizontally to be reduced (e.g., to 79 from 80).
In theory, a similar problem could also exist vertically but this is
• less likely and has never been reported. This can be remedied by
specifying "XLT= 1", which provides an additional translation to en-
sure that (0,0) in the PS page transforms to (0,0) on the device. This
occurs regardless of any other parameters (including "XFM=0").
"XLT=0" will not apply this correction.

The default for PMPRII\IT is "COP=1 ARE=C FIT=S XFM=1 XLT=O COL=M" for
a mono printer and "COP=1 ARE=C FIT=S XFM=1 XLT=O COL=C" for a color
printer. Note that these defaults will not give the same results as printing to an
OD DIRECT DC. The most noticeable difference is that OD_QUEUED output is,
by default, scaled to fit with one dimension centered. This default scaling may
result in an incoITect size and might prevent a required font match from occurring.
In addition, operations such GpiBitBlt that are specified using device coordi-
266 OS/2 PRESENTATION MANAGER GPI

mates are unaffected by any scaling or translation arising from these parameters
andarethereforelikelytoappearintheincorrectpositionrelativetoother..output
if the output is scaled to fit. This will occur unless these parameters are explicitly
specified to force the output to be real size and positioned with its origin at the
bottom left comer of the output area (i.e., XFM=O XLT=1). This can also be
achieved by defining the PS Page and page units to exactly reflect the size of the
outputarea(orinthecaseofPU_ARBITRARYensuringthatthepageaspectratio
exactly matches that of the output area).
Other queue processors may define their own requirements for this parameter.
For other DC types (or default) this parameter can be NUIL or omitted.
APPENDIX 3

Introduction to Transforms and Matrices

Thansformi matrices provide a convenient and simple way of expressing and


manipulating most required coordinate transformation operations including:
rotation;
scaling (i.e., making larger or smaller);
translation (i.e. , repositioning);
shear (i.e., creating an oblique or italicised appearance); and
inversion (or reflection).
These are illustrated in Figure A3-1.
The transformation of any point (x,y) to a new position (x',y) by any of the above
operations can be expressed by the general equations

x, = ar + cy + e
y' = bx + dy + f

that can be represented in matrix formi as:

This is illustrated by the equations below (with the corresponding matrices shown
on the right):

267
268 OS/2 PRESENTATION MANAGER GPI

Figure A3.1 Common Thransform operations.

Counterclockwise rotation through R degrees:

x' = xCosR - ysinR


y' = xsinR + ycosR

(a=CosR, b=SinR, c=-SinR, d=CosR, e=0, f=0)

Scaling x and y by scale factors of sl and s2 respectively:

(a=sl, b=O, c=0, d=s2, e=0, f=0)


INTRODUCTION TO TRANSFORMS AND MATRICES 269

'Thanslation of x by tl and y by t2:

x' = x + tl
y' = y + t2

(a=1, b=0, c=0, d=1, e=tl, f=t2)

Horizontal shear by an angle of S degrees from the vertical:

;;=;+yTans [ianss: :I

(a=1, b=0, c=Tans, d=1, e=0, f=0)

x inversion (i.e., reflection about y axis):

x, = -x
y I _- y

(a=-1, b=0, c=0, d=1, e=O, f=0)

y inversion (i.e., reflection about x axis):

x,=x
y' = -y

(a=1, b=0, c=0, d=-1, e=0, f=0)

Note that inversion of both x and y is equivalent to 180 degree rotation.


Identity:

x,=x
y'=y

(a=1, b=0, c=0, d=1, e=0, f=0)

Matrix algebra defines the multiplication of a (1x3) and (3x3) matrix as:

[gp+hs+iv gq+ht+iw gr+hu+ix]


270 OS/2 PRESENTATION MANAGER GPI

and multiplication of a (3x3) and (3x3) matrix as:

+hs+iv gq+ht+iw gr+hu


+ks+lv jq+kt+lw jr+ku
I: p+ns+ov mqThthcw mr+n

The equations x±ax+cy+e and yEbx+dy+f are thus expressed in matrix form as:

[x,y,1] = [x y 1] .

The ones and zeros in column three of these matrices exist to enable the normal
rules of matrix algebra to be applied unchanged for coordinate transformations.
They ensure consistency between the dimensions of input and output matrices (of
matrix multiplications) and will, in fact, ensure that ones and zeros appear in the
same positions of all matrices produced by matrix multiplication using such
matrices.
Using matrix algebra to multiply out the (1x3) and (3x3) matrix expression on
the right above, gives a (1x3) matrix containing the required values for (x',y). That
is:

[xyl] . [ar+cy+e bx+dy+f l]

It follows that any of the above operations (rotation, scale, shear, etc.) can be
represented by the single (3x3) matrix as shown earlier with each of the equations.
Furthermore, any combination of such (rotation, scale, shear, etc.) matrices can be
concatenated by matrix multiplication into a single matrix of the above form
(although order of concatenation is important).
The identity or unit matrix (I) shown earlier produces output values that are
identical to its input values. The identity matrix represents the initial or reset
value of most GPI transform matrices.
The system frequently needs to determine the inverse of a matrix in order to
back transformi coordinates from an output to an input coordinate space. The
inverse of a matrix A is denoted by A-1

If X' = X.A then X = X'.A-1 and A.A-1 = I (where X' = [x' y' 1] and X = [x y 1])

For some matrices, it is impossible to find an inverse (e.g., a matrix that trans-
forms more than one input point to a single output point). Such matrices are said
to be singular and will cause the system to log an error (PMERR_COORDI-
NATE_OVERFLOW).
A word of caution is required about the use of coordinate transformation
matrices. The equations described earlier would all produce rotation, scaling,
INTRODUCTION TO TRANSFORMS AND MATRICES T]\

trfu rfu

Figure A3.2 Rotation about Origin and Bottom Left of Figure.

shear, etc., relative to the origin (0,0). If, as is likely, a figure to be transformed is
not located at the origin and the transformation is required to be relative to a point
on the figure such as the bottom left corner, transformation relative to the origin
will introduce an undesired translation. This is illustrated (for rotation) in Figure
A3-2. The simplest remedy for this is to (1) provide a matrix to translate the figure
such that its bottom left corner (say) is at the origin; (2) provide a second matrix
to perform the required operation (e.g., rotation); and (3) provide a third matrix to
translate the figure back to its required position. For example, for rotation this
might appear as follows:

[x' y' 1] = [x y 1]

I;e :f ;loiR
(Where (e,f) are the coordinates of the center of rotation, and R is the angle of
rotation (counterclockwise) in degrees.) Clearly, it would be possible to multiply
out the above expression to reduce the three matrices to a single matrix. However,
this is unnecessary as the system provides options (e.g., TRANSFORM_ADD) that
enable transforms to be incrementally updated as would be required here. The
system can, in fact, perform all required matrix multiplications.
APPENDIX 4

Sample MetaFile lnternals

A MetaFile consists of a series of structured fields as documented in the IBM OS#


Programming Reference and Mixed Document Architecture Reference. Below is
an example of a real MetaFile in hex with the different fields identified. Following
this is a list of examples of MetaFile escape orders reflecting functions not
supported by the interchange architecture or resource and environment changes
that occur during drawing.
Begin Document
(A8) (A8) (00) (cO) (cO) (30) (30) (30) (30) (30) (30) (30) (31)

(OC) (00)
@4) (03) (52)

Begin Resource Group


(00> (io) a]3) (A8) tc6) (00) too) (Oot (30> t3O) t3O) (30) t3O) (30> (30) (32)

Begin Color Attribute Table (PS Ijogical Color Table)


(00) (10) @3) (A8) (77) (cO) (cO) (cO) (30) (30) (30) (30) (30) (30) (30) (34)

Color Attribute Table (PS I.logical Color Table)


(00)
(OF)
(OF)
(OF)
(OF)
(OF)
(OF)

272
SAMPLE METAFILE INTERNALS 273

Color Attribute Table (PS Ijogical Color Table) (continued)

End Color Attribute Table (PS Logical Color Table)


(00) (10) @3) (A9) (77) (cO) (cO) (00) (30) (30) (30) (30) (30) (30) (30) (34)

Begin Image. Object (Bitmap 1) -Image Name: 3F] 34 33 3C 30 30 30 34 (Hex)


too) tio) a]3) tA8) GB) (cO) (cO) (cO) (3E) (34) (33) (3c) (30) t3O) (30) (34)

Begin Resource Group (Bitmap 1 Color Table)


(cO) (10) @3) (A8) (C6) (cO) (cO) (00) (30) (34) (30) (30) (33) (3C) (3E) (34)

Begin Color Attribute Table (Bitmap 1 Color Table)


(00) (10) @3) (A8) (77) (00) (00) (00) (30) (34) (30) (30) (33) (3C) (3E) (34)

Color Attribute Table (Bitmap 1 Color Table)


(00) (ic) @3) a3O) (77> (00) (cO) (00) (cO) (cO) (01)
(11) (01) (cO) (01) (00) (cO) (cO) (08) (08) (08) (03) (cO) (00) (00) GF) qF)
GF)
End Color Attribute Table (Bitmap 1 Color Table)
(cO) (io) a]3) (A9) (77> (cO) (cO) (00) (30) (34) (30) (30) (33) (3c) (3E) (34)

End Resource Group (Bitmap 1 Color Table)


(cO) (10) @3) (A9) (C6) (00) (cO) (00) (30) (34) (30) (30) (33) (3C) (3E) (34)

Begin Object Environment Group (Bitmap 1 Color Table)


(00) (10) @3) (A8) (C7) (00) (cO) (00) (3E) (34) (33) (3C) (30) (30) (30) (34)

Map Color Attribute Table (Bitmap 1 Color Table)


(cO) (1A) @3) (AB) (77) (cO) (cO) (00) (cO) (12)
(OC) (02) (84) (cO) (30) (34) (30) (30) (33) (3C) (3E) (34)
(04) (24) (07) (01)

End Object Environment Group (Bitmap 1 Color Table)


(cO) (10) @3) (A9) (C7) (cO) (cO) (00) (3E) (34) (33) (3C) (30) (30) (30) (34)
274 OS/2 PRESENTATION MANAGER GPI

Image Data Descriptor (Bitmap 1 Data)


(00) (11) @3) (A6) GrB) (cO) (cO) (cO) (01) (cO) (C8) (01) (OA) (00) (OA) (00)
(OA)

Image Hcture Data (Bitmap 1 Data)


@3) a]E) GB) (cO) (cO) (00)

Q7F)
(00) (00) (cO) (cO) (00) (OA) (cO) (OA)
(03)

Image Hcture Data (Bitmap 1 Data)


(cO) (38) @3) qE) QrB) (cO) (cO) (00)
GE) (92) (cO) (28) qF) (CO) (cO) (00) (9E) (7A) @E) (CO) (9E) (40) (OA) (02)
(cO)(ci) (cO) (cO) (cc) (cO) (02) (00) a]D) (cO) (00) (80) all) (ci) (00) (00)
G3) (CO) (80) (02) Gr3) (CO) (00) (00) qF) (CO) (03) (cO) (93) (00) (71) (00)

End Image Object (Bitmap 1)


(00) (10) @3) (A9) GB) (cO) (00) (00) (3E) (34) (33) (3C) (30) (30) (30) (34)

Begin Image Object (Bitmap 2) -Image Name: 38 34 22 3C 30 30 30 34 (Hex)


(cO) (io) a]3) (A8) GB) (00) (00) (00) (38) (34) (33) (3c) (30) (30) (30) (34)

Begin Resource Group (Bitmap 2 Color Table)


(00) (10) @3) (A8) (C6) (00) (00) (00) (30) (34) (30) (30) (33) (3C) (38) (34)

Begin Color Attribute Table (Bitmap 2 Color Table)


(cO) (10) @3) (A8) (77) (00) (cO) (00) (30) (34) (30) (30) (33) (3C) (38) (34)

Color Attribute Table (Bitmap 2 Color Table)


(00) (1C) @3) @0) (77) (cO) (00) (00) (cO) (00) (01)
(11) (Oi> (cO> (Oi> (00> (cO> tco> (08) (08) (08) t03) (00) (cO) (00) arF> GF)
GF)
End Color Attribute Table (Bitmap 2 Color Table)
(00) (10) @3) (A9) (77) (cO) (00) (00) (30) (34) (30) (30) (33) (3C) (38) (34)

End Resource Group (Bitmap 2 Color Table)


(cO) (10) @3) (A9) (C6) (cO) (cO) (00) (30) (34) (30) (30) (33) (3C) (38) (34)

Begin Object Environment Group (Bitmap 2 MCA)


(00) (10) @3) (A8) (C7) (cO) (cO) (00) (38) (34) (33) (3C) (30) (30) (30) (34)
SAMPLE METAFILE INTERNALS T]5

Map Color Attribute Table (Bitmap 2 MCA)


(cO) (1A) @3) (AB) (77) (cO) (cO) (cO) (cO) (12)
(OC) (02) (84) (cO) (30) (34) (30) (30) (33) (3C) (38) (34)
(04) (24) (07) (01)

End Object Environment Group (Bitmap 2 MCA)


(cO) (10) @3) (A9) (C7) (cO) (cO) (00) (38) (34) (33) (3C) (30) (30) (30) (34)

Image Data Descriptor (Bitmap 2 Data)


(cO) (11) @3) (A6) GB) (cO) (cO) (00) (01) (cO) (C8) (01) (OA) (00) (OA) (00)
(OA)

Image Hcture Data (Bitmap 2 Data)


a)3) a]E) GB) (cO) (cO) (00)

qF)
(00) (cO) (00) (00) (OA) (00) (OA)

Image Hcture Data (Bitmap 2 Data)


(cO) (38) a]3) a]E> GB) (cO)
GE) (92) (cO) (28) GF) (CO)
GE4) (C1) (20) (01) ql) (CO)
(CE) (41) (84) (01) (9F) (cO)

End Image Object (Bitmap 2 Data)


(cO) (10) @3) (A9) GB) (cO) (cO) (00) (38) (34) (33) (3C) (30) (30) (30) (34)

Begin Graphics Object


(cO) (io) q]3) (A8) a3B) (00) (cO) (00) (30) (30) (30) (30) (30) (30) (30) (37)

Begin Object Environment Group


(cO) (10) @3) (A8) (C7) (cO) (00) (00) (30) (30) (30) (30) (30) (30) (30) (37)

Map Color Attribute Table


(cO) (16) @3) (AB) (77) (cO) (cO) (cO) (cO) (OE)
(OC) (02) (84) (00) (30) (30) (30) (30) (30) (30) (30) (34)

Map Coded Font (Default Font I.cid = 0)


(cO) (cO) (00) (cO) (18)
(co) (co) (oo) (co) (co) (oo) (co)
(04)
(06)
276 OS/2 PRESENTATION MANAGER GPI

Map Coded Font (I.ogical Font Leid = 1)


(cO) (cO) (cO) (cO) (50)
(4F) (4E) (54) (30) (31) (cO) (43)

(0o) (oF) (co) (oC) (co) (co) (co) (co) (co) (co) (co) (co)

(75) (72) (69) (65) (72) (cO) (53) (01) (43) (cO)
(00) (00) (00) (cO) (40) (3F) ®8) (3F) (8F) (05)

Map Coded Font (Ijogical Font Leid = 2)


(8A) (00) (cO) (00) (cO) (50)
(46) (4F) (4E) (54) (30) (31) (cO) (46)

(00) (OC) (00) (09) (00) (cO) (00) (cO) (cO) (00) (00) (00)

(03) (52)
(43) (6F) (75) (72) (69) (65) (72) (cO) (53) (01) (43) (00)
(iA) toi) (cO) (00) (cO) (cO) (40) (3F) a]8) (3F) (8F) (05)

Map Data Resource (Bitmap 1) -Image Name: 3E 34 33 3C 30 30 30 34 (Hex)


Bitmap Handle: Ox04cO3CE4
(cO) (1D) @3) (AB) (C3) (cO) (cO) (00) (cO) (15)
(OC) (02) (84) (cO) (3E) (34) (33) (3C) (30) (30) (30) (34)
(07) (22) (io) (04) (00) (3c> a]4)

Map Data Resource (Bitmap 2) - Image Name: 38 34 22 3C 30 30 30 34 (Hex)


Bitmap Handle: Ox04003C84
(cO) (iD) a]3) (AB) (c3) (cO) (cO) (00) (cO) (15)
(OC) (02) (84) (cO) (38) (34) (33) (3C) (30) (30) (30) (34)
(07) (22) (10) (04) (00) (3C) (84)

End Object Environment Group


(cO) (io) a]3) (A9) (c7) (cO) (cO) too) t3O) (30) (30) (30) (30> (30) (30> (37)

Graphics Data Descriptor (GDD)


(cO) (88) a]3) (A6) @8) (cO) (cO) (00)

Specify GVM subset (GDD)


G7) (07) q30) (cO) (00) (23) (01) (01) (05)

Set Picture Descriptor (GDD - PS Page Units, etc.)


ar6) (28) (60) (00) (05> (cO> (01) (00) (cO) (cO) (Oi> (cO) (cO) (00) (00) (00)
(cO) (00) (cO) (cO) (00) (cO) (80) (02) (cO) (cO) (00) (cO) (cO) (00) (5E) (01)
SAMPLE METAFILE INTERNALS T]l

Set Hcture Descriptor (GDD -PS Page Units, etc.) (continued)


(co) (co) (co) (co) (oo) (co) (oo) (oo) (co) (co)

Set Current Defaults (GDD)


Set Default Parameter Format - GPIF_SHORTh/GPIF_LONG PS coordinate
format
(21) (07) (08) a]O) (00) (8F) (cO) (05) (05)

Set Current Defaults (GDD) Set Default Viewing 'Thansform


(21) (1C) (07) (CC) (OC) (8F) (cO) (00) (02) (cO) (00) (cO) (cO) (00) (00) (00)
(cO) (cO) (cO) (cO) (02) (cO) (14) (00) (cO) (cO) (14) (cO) (cO) (00)

Set Current Defaults (GDD) Set Default Character Attributes


(21) (10) (02) (40) (00) (8F) (09) (00) (cO) (cO) (OC) (cO) (cO) (00) (00) (00)
(cO) (cO)

Set Current Defaults (GDD) Set Default Marker Attributes


(21) (OC) (03) (40) (00) (8F) (09) (00) (cO) (cO) (09) (cO) (cO) (00)

Set Bitmap Identifier - handle: 84 3C cO 04 (hex) Leid: 04 (hex)


a]7) (07) (80) (cO) (84) (3c) (00) (04) (04)

Graphics Data
(cO) (66) @3) a]E) a3B) (cO) (cO) (00)

Begin Segment (Segment ID = OxorxxrmA -unchained called segment)


(70) (OE) (cO) (cO) (00) (OA) (50) (80) (cO) (4E) (00) (cO) (cO) (00) (00) (00)

Set Indexed Color (GSICOL)


(A6) (04) (cO) (04) (00) (00)

Set Current Position (GSCP)


(21) (08) (OA) (cO) (00) (cO) (OF) (00) (cO) (cO)

Line at Current Position (GCLINE)


(81) (08) (32) (cO) (00) (00) (OF) (00) (cO) (cO)

Set Pattern Set (GSPS)


(08) (04)

Set Indexed Color (GSICOL)


(A6) (04) (cO) (02) (00) (cO)
278 OS/2 PRESENTATION MANAGER GPI

Begin Area (GBAR)


(68) (AO)
Set Current Position (GSCP)
(21) (08) (32) (cO) (00) (cO) (32) (00) (cO) (cO)

Line at Current Position (GCLINE)


(81) (08) (96) (cO) (00) (cO) (96) (00) (cO) (cO)

Line at Current Position (GCLINE)


(81) (08) (2C) (01) (00) (cO) (32) (cO) (cO) (cO)

Line at Current Position (GCLINE)


(81) (08) (32) (cO) (00) (cO) (32) (00) (cO) (cO)

End Area (GEAR)


(60) (cO)

Graphics Data
(Oi> (66> @3> ®E) a3Bt too) toot toot

GDF Begin Segment Order (Segment ID = 0)


(70) (OE) (cO) (00) (00) (cO) (70) (00) (cO) (16) (00) (00) (cO) (00) (00) (00)

Extended Escape (MetaFile Escape Order - GpisetGraphicsField OxOAcO)


qE)@5) (cO) (12) (00) (OA) (00) (00) (cO) (cO) (00) (cO) (cO) (00) (90) (01)
(cO) (cO) (90) (01) (00) (cO)

GDF Begin Segment Order (ID = OxOOcOcO14 -chained segment)


(70) (OE) (cO) (cO) (00) (14) (50) (00) (cO) (2E) (00) (cO) (cO) (00) (cO) (00)

Bitblt (GBBLT)
@6)(2c) (cO) (cO) (cc) (cO) a]4) (3c) (cO) (04) (00) (01) (01) (00) (cO) (00)
(cO) (cO) (64) (cO) (00) (cO) (OA) (00) (cO) (cO) (6E) (cO) (cO) (00) (cO) (cO)
(cO) (cO) (cO) (00) (00) (cO) (OA) (00) (cO) (cO) (OA) (cO) (cO) (00)

Begin Segment (ID = OxOOOcoolE -chained segment with prolog)


(70) (OE) (cO) (cO) (00) (1E) (50) (10) (cO) (9C) (00) (cO) (cO) (00) (cO) (00)

Set Viewing Thansform (GSTV)


(31) (1C) (00) (00) (CC) (OC) (cO) (00) (02) (00) (00) (cO) (00) (00) (00) (00)
(cO) (cO) (cO) (cO) (02) (cO) (cO) (00) (cO) (00) (00) (cO) (cO) (00)
SAMPLE METAFILE INTERNALS T]9

Push and Set Model Thansform (GPSTM)


(64) (1C) (cO) (01) (CC) (OC) (cO) (cO) (01) (cO) (cO) (cO) (cO) (00) (cO) (cO)
(cO) (cO) (cO) (00) (01) (cO) (cO) (cO) (cO) (cO) (cO) (cO) (cO) (00)

End Hologue (GEPROL)


(3E) (cO)

Begin Element (GBEL - Call Segment)


@2) (04) (07) (cO) (00) (cO)

Push and Set Model Thansform (GPSTM - Call Segment)


(64) (1C) (cO) (01) (CC) (OC) (cO) (00) (01) (cO) (cO) (cO) (cO) (00) (cO) (cO)
(cO) (cO) (cO) (cO) (01) (cO) (cO) (00) (cO) (cO) (cO) (cO) (cO) (00)

Call Segment (GCALLS - Call Segment)


(07) (06) (00) (00) (OA) (cO) (00) (00)

Pop (GPOP -Call Segment)


(3F) (00)

End Element (GEEL - CAll Segment)


(49) (cO)

End Image (GEIMG)


(93) (cO)

Set Indexed Color (GSICOL)


(A6) (04) (cO) (02) (00) (cO)

Set Current Position (GSCP)


(21) (08) (OA) (cO) (00) (cO) (14) (00) (cO) (cO)

Line at Current Position (GCLINE)


(81) (08) (OA) (00) (00) (cO) (28) (00) (cO) (00)

Set Character Set (GSCS)


(38) (01)

Character String Move at Current Position (GCCHSTM)


@1) (06) (41) (42) (43) (44) (45) (46)

Set Character Set (GSCS)


(38) (02)
280 OS/2 PRESENTATION MANAGER GPI

Character String Move at Current Position (GCCHSTM)


®1) (06) (47) (48) (49) (4A) (48) (4C)

GDF Begin Segment Order (ID = 0 - null segment zero with prolog)
(70) (OE) (00) (cO) (00) (cO) (71) (10) (cO) (3E) (cO) (cO) (cO) (00) (00) (cO)

Set Viewing Thansform (GSTV)


(31) (1C) (cO) (cO) (CC) (OC) (cO) (00) (01) (cO) (cO) (cO) (cO) (00) (00) (00)
(cO) (cO) (cO) (cO) (01) (cO) (cO) (00) (cO) (cO) (cO) (cO) (cO) (00)

fish and Set Model Thansform (GPSTM)


(64) (1C) (00) (01) (CC) (OC) (cO) (00) (01) (cO) (cO) (cO) (cO) (00) (00) (00)
(cO) (cO) (cO) (cO) (01) (cO) (cO) (00) (cO) (cO) (cO) (cO) (cO) (00)

End Prologue (GEPROL)


(3E) (cO)

End Graphics Object


(00) (10) @3) (A9) @8) (00) (cO) (00) (30) (30) (30) (30) (30) (30) (30) (37)

End Resource Group


(00) (10) @3) (A9) (C6) (cO) (cO) (00) (30) (30) (30) (30) (30) (30) (30) (32)

End Document
(cO) (10) @3) (A9) (A8) (cO) (00) (00) (30) (30) (30) (30) (30) (30) (30) (31)

Examples of MetaFile escape orders:

Ijong Escape (Gpisetpel OxO1 )


a]5)(OA) (80> toi> (32) (cO> too) too> t32> (cO) (00> (cO>

Ijong Escape (GpiBitBlt Ox02)


(cO) (04) GO) (28) (00) (04) (cO)
(cO) (00) (64) (cO) (00) (cO) (OA)
(cO) (00) (cO) (cO) (00) (cO) (OA)

Extended Escape (GpicreateljogcolorTable Oxolun)


GE) @5)
(cO) (cO)
(cO) (cO)
(80) (cO)
(cO) (cO)
GF) (cO)
SAMPLE METAFILE INTERNALS 281

Extended Escape (GpicreateljogFont Ox0200)


GE)@5) (cO) (46) (cO) (02) (46) (4F) (4E)
(cO) (cO) (38) (cO) (00) (cO) (cO) (cO) (cO)
(72) (cO) (67) (01) (00) (cO) (cO) (cO) (CA)
(67) (01) (87) (cO) (19) (13) a]8) (2c) (c6)
(cO) (cO) (06) (cO) (cO) (cO) (cO) (cO) (cO)

Extended Escape (GpiDeletesetld Ox0300)


OE)@5) (cO) (06) (00) (03) (01) (cO) (cO) (cO)

Extended Escape (GpiResetps 0K05cO)


GE>a]5) (cO) t06) (00> (05) (04) tco> (cO) too)

Extended Escape (GpisetDrawcontrol - DCTL_DISPLAY 0x0600)


QrE)@5) (cO) (06) (00) (06) (cO) (00) (cO) (cO)

Extended Escape (GpisetBitmapld Ox07cO)


arE)@5) (cO) (OA) (00) (07) (24) (3A) (cO) (04) (16) (cO) (cO) (00)

Extended Escape (Gpisetcp OxO800)


GE)@5) (cO) (06) (00) (08) a35) (01) (cO) (cO)

Extended Escape (GpisetDefaultviewMatrix OxO9cO)


GE)a]5) (cO) (iE) (00) (09) (cO) (00) (02) (cO) (00) (00) (cO) (00) (00) (00)
(cO) (cO) (cO) (cO) (02) (cO) (14) (00) (cO) (cO) (14) (cO) (00) (00) (00) (00)
(cO) (cO)

Extended Escape (GpisetGraphicsField OxOA00)


arE)a]5) (cO) (12) (00) (OA) (OA) (00) (cO) (cO) (OA) (cO) (cO) (00) a]8) (03)
(cO) (cO) ®8) (03) (00) (cO)

Extended Escape (GpiErase OxOC00)


GE)@5) (cO) (02) (00) (OC)

Extended Escape (GpilntersectclipRectangle OxOD00)


¢iE>@5) (cO) (12) (00) toD) (OA) (00) (cO) (cot (OA) (cO) (00) (00) a]8) (03)
(cO) (cO) G8) (03) (00) (cO)

Extended Escape (GpioffsetclipRegion OxOEcO)


GE)@5) (cO) (12) (00) (OE) (64) (00) (cO) (cO) (96) (cO) (00) (00) (00) (00)
(co) (co) (co) (co) (co) (co)

Extended Escape (GpiExcludeclipRectangle OxOF00)


GrE)@5) (co) (12) (oo) (oF) (oA) (oo) (co) (co) (oA) (cO) (cO) (00) a]8) (03)
(cO) (cO) G8) (03) (00) (cO)
282 OS/2 PRESENTATION MANAGER GPI

Extended Escape (GpisetclipRegion Oxl000)


GE)@5) (cO) (36) (00) (10) (03) (cO) (cO)
(cO) (cO) (78) (cO) (00) (cO) (90) (01) (cO)
(cO) (cO) (90) (01) (cO) (cO) @C) (cO) (cO)
(cO) (cO) (78) (cO) (cO) (cO) (C8) (cO) (cO)

Extended Escape (GpisetclipPegion -NUIL 0xll00)


arE)@5) (co) (o6) (co) (11) (co) (co) (co) (co)

Extended Escape (GpipaintRegion Oxl200)

Extended Escape (DevEscape code=Ox3FAD 0xl300)


arE)@5) (cO) (Oc) (00) (13) (AD> (3F> (cO) (cO) (02) (cO) (cO) (00) (01) (00)

Extended Escape (Gpisaveps 0xl400)


qE)@5) (cO) (02) (00) (14)

Extended Escape (GpiRestoreps 0xl5cO)


GE)@5) (cO) (06) (00) (15) (01) (00) (cO) (cO)

Extended Escape (GpisetDefAttrs Oxl6cO)


arE)a]5) (cO) (24) (00) ti6) (01) (00) (cO) too) ar5) (01) (cO) (00) (01) (00)
(cO) (cO) (11) (cO) (00) (cO) (02) (00) (87) (cO) (00) (cO) (01) (00) (01) (cO)
(cO) (cO) (07) (cO) (01) (cO) (01) (00)

Extended Escape (GpisetDefTag Oxl 700)


GE)a]5) (cO) (06) (00) (17) (02) (00) (cO) (cO)

Extended Escape (GpisetDefviewingLimits Oxl8cO)


arE)@5) (cO) (12) too) (18) toA) (00) (cO> (cO) (OA) (cO) (00) (00) a]8) (03)
(cO) (cO) a]8) (03> (00) (cO)

Extended Escape (GpisetDefArcparams Oxl9cO)


arE)a]5) (cO) (12) (00) (19) (02) (cO) (cO) (cO) (02) (cO) (cO) (00) (cO) (00)
(co) (co) (co) (co) (oo) (co)
APPENDIX 5

Sample Orders

Below are salnple orders that may be found in MetaFiles or used with and
returned by GpifutData, GpiGetData, GpiElement, and GpiQueryElement. The
"short format" orders apply to a PS created using the GPIF_SHORT Gpicreateps
option. The "push and set" versions of the orders are generated if the attribute
mode for the PS is set to AM_PRESERVE. The long and short format versions of
a particular order are not, in all cases, equivalent.
Arc at Given Position (GARC)
(C6) (18) (50) (cO) (00) (cO) (50) (00) (00) (cO) (32) (00) (00) (00) (32) (00)
(cO) (cO) (64) (cO) (00) (cO) (32) (00) (cO) (00)

Arc at Given Position (GCARC - short format)


(C6)(OC) (50) (cO) (50) (cO) ((32) (00) (32) (00) (64) (cO) (32) (00)

Arc at Current Position (GCARC)


(86) (10) (32) (cO) (00) (cO) (32) (00) (cO) (cO) (64) (cO) (cO) (00) (32) (00)
(cO) (cO)

Arc at Current Position (GCARC - short format)


(86) (08) (32) (cO) (32) (cO) (64) (cO) (32) (cO)

Begin Area (GBAR)


(68) (AO)

Begin Element (GBEL - Call Segment)


@2) (04) (07) (cO) (00) (cO)

283
284 OS/2 PRESENTATION MANAGER GPI

Begin Image at Given Position (GCBIMG - short format)


a)1)(OE) (50) (cO) (00) (cO) (50) (cO) (cO) (cO) (00) (cO) (cO) (20) (cO) (38)

Begin Image at Given Position (GCBIMG - short format)


a)1)(OA) (50) (cO) (50) (cO) (cO) (00) (cO) (20) (cO) (38)

Begin Image at Current Position (GCBIMG)


(91) (06) (cO) (cO) (00) (20) (cO) (38)

Begin Path
@0) (06) (cO) (00) (01) (cO) (cO) (00)

Bezier Curve at Given Position (GBEZ)

Bezier Curve at Given Position (GBEZ - short format)

Bezier Curve at Current Position (GCBEZ)

Bezier Curve at Current Position (GCBEZ - short format)


(00) (96) (00) (7D) (cO)
(cO) (96) (cO) G1) (cO)
(96) (cO) (45)
(96) (cO) (A9)
SAMPLE ORDERS Z#5

Bitblt (GBBLT)
are)(2c) (cO) (cO) (cc) (cO) G4) (3c) (cO) (04) (cO) (01) (01) (cO) (cO) (cO)
(cO) (cO) (64) (cO) (00) (cO) (OA) (cO) (cO) (cO) (6E) (cO) (cO) (cO) (cO) (cO)
(cO) (cO) (cO) (cO) (00) (cO) (OA) (00) (cO) (00) (OA) (00) (cO) (cO)

Bitblt (GBBLT - short format)


@6) (24) (cO) (cO) (CC) (cO) (50) (2C) (cO) (04) (cO) (01) (01) (cO) (cO) (cO)
(64) (cO) (OA) (cO) (6E) (cO) (cO) (00) (cO) (cO) (cO) (cO) (cO) (cO) (OA) (cO)
(cO) (00) (OA) (cO) (cO) (cO)

frox at Given Position (GBOX)


(CO)(1A) (40) (cO) (50) (cO) (00) (cO) (50) (cO) (cO) (cO) (20) (00) (cO) (cO)
(20) (cO) (cO) (cO) (00) (cO) (cO) (cO) (cO) (00) (00) (cO)

Box at Given Position (GBOX - short format)


(CO)(OE) (40) (cO) (50) (cO) (50) (00) (20) (cO) (20) (cO) (cO) (cO) (cO) (cO)

Box at Current Position (GCBOX)


(80) (12) (40) (cO) (20) (cO) (cO) (cO) (20) (cO) (00) (cO) (cO) (00) (cO) (cO)
(co) (co) (co) (co)

Box at Current Position (GCBOX - short format)


(80) (OA) (40) (cO) (20) (cO) (20) (00) (cO) (cO) (00) (cO)

Call Segment (GCAILS)


(07) (06) (cO) (cO) (OA) (cO) (cO) (00)

Character String at Given Position (GCHST)


(C3) (17) (64) (cO) (00) (cO) (64) (00) (cO) (cO) (47) (70) (69) (43) (68) (61)
(72) (53) (74) (72) (69) (6E) (67) (41) (74)

Character String at Given Position (GCHST - short format)


(C3) (13) (64) (cO) (64) (cO) (47) (70) (69) (43) (68) (61) (72) (53) (74) (72)
(69) (6E) (67) (41) (74)

Character String at Current Position (GCCHST)


(83) (OF) (47) (70) (69) (43) (68) (61) (72) (53) (74) (72) (69) (6E) (67) (41)
(74)

Character String Extended at Given Position (GCHSTE)


GE)GO) (cO) (76) (64) (cO) (co)
(cO) (cO) (5A) (cO) (cO) (cO) (AE)
(47) (70) (69) (43) (68) (61) (72)
(41) (74) (14) (cO) (cO) (cO) (14)
(cO) (cO) (14) (cO) (00) (cO) (14)
286 OS/2 PRESENTATION MANAGER GPI

Character String Extended at Given Position (GCHSTE) (continued)


(cO) (cO) (14) (cO) (cO) (cO) (14) (cO) (cO) (cO) (14) (cO) (cO) (cO) (14) (cO)
(cO) (cO) (14) (cO) (cO) (cO) (14) (cO) (cO) (cO) (14) (cO) (cO) (cO) (14) (cO)
(cO) (cO) (14) (cO) (00) (cO) (14) (cO) (cO) (cO)

Character String Extended at Given Position (GCHS'IH - short format)

Character String Extended at Current Position (GCCHSTE)


GE)
(cO)
(74)
(14)
(14)
(14)
(14)

Character String Extended at Given Position (GCCHSTE -short format)

Character String Move at Given Position (GCHSTM)


¢1) (17) (64) (cO) (00) (cO) (64) (00) (cO) (cO) (47) (70) (69) (43) (68) (61)
(72) (53) (74) (72) (69) (6E) (67) (41) (74)

Character String Move at Given Position (GCHSTM - short format)


G1) (13) (64) (00) (64) (cO) (47) (70) (69) (43) (68) (61) (72) (53) (74) (72)
(69) (6E) (67) (41) (74)

Character String Move at Current Position (GCCHSTM)


a3i)toD) (47) t7O> (69) t43) (68) t6i> t72) t53) t74) (72> t69> (6E) (67>

Close Figure (GCIFIG)


(7D) (cO)

Comment (GCOMT)
(01) (07) (43) (4F) (4D) (4D) (45) (4E) (54)

End Area (GEAR)


(60) (cO)
SAMPLE ORDERS TRT

End Element (GEEL)


(49) (cO)

End Image (GEIMG)


(93) (cO)

End of Symbol Definition (GESD)


a7F)

End Path
(7F) (cO)

End Prologue (GEPROL)


(3E) (cO)

Escape (GESCP)
@5)(OA) (80) (01) (32) (00) (cO) (00) (32) (cO) (00) (cO)

Extended Escape (GEESCP)


GE)a)5) (cO) (06) (00) (17) (02) (00) (cO) (cO)

Fill Path (GF-)


@7) (06) (20) (00) (01) (00) (cO) (00)

Fillet at Given Position (GFLT)

Fillet at Given Position (GFLT - short format)


(C5) (24) (50) (00) (50) (00) (48) (00) (OE) (01) (7D) (cO) (OA) (00) (AF) (00)
(OE) (01) ql) (00) (OA) (cO) (13) (01) (OE) (01) (45) (01) (OA) (00) (77) (01)
(OE) (01) (A9) (01) (OA) (00)

Fillet at Current Position (GCFLT)

Fillet at Current Position (GCFLT - short format)


(85) (20) (48) (cO> (OE) (01) (7D) (00) (OA) (cO) (AF) (cO) (OE) (01) a]i) (00)
288 OS/2 PRESENTATION MANAGER GPI

Fillet at Current Position (GCFIJI' - short format) (continued)


(OA) (cO) (13) (01) (OE) (01) (45) (01) (OA) (cO) (77) (01) (OE) (01) (A9) (01)
(OA) (cO)

Fhll Arc at Given Position (GFARC)


(C7)(OC) (50) (cO) (00) (cO) (50) (cO) (cO) (cO) (cO) (cO) (40) (cO)

Full Arc at Given Position (GFARC - short format)


(C7) (06) (50) (cO) (50) (cO) (cO) (40)

Fhll Arc at Current Position (GCFARC)


(87) (04) (cO) (cO) (40) (cO)

Full Arc at Current Position (GCFARC - short format)


(87) (02) (00) (40)

Image Data (GIMD)


(92) (04) (cO) (cO) (03) (cO)

I+abel (GIRL)
a]2) (05) (4c) (41) (42) (45) (4ct

Line at Current Position (GCLINE)


(81) (08) qA) (00) (00) (00) (64) (00) (cO) (cO)

Line at Current Position (GCLINE - short format)


(81) (04) qA) (00) (64) (cO)

Line at Given Position (GLINE)


(C1) (10) (50) (cO) (00) (cO) (50) (00) (cO) (cO) qA) (cO) (cO) (00) (64) (cO)
(cO) (cO)

Line at Given Position (GLINE - short format)


(C1) (08) (50) (00) (50) (cO) qA) (00) (64) (cO)

Marker at Given Position (GI\ffiK)


(C2) (08) (82) (cO) (00) (cO) (5F) (00) (cO) (cO)

Marker at Given Position (GMRK - short format)


(C2) (04) (96) (cO) (96) (cO)

Marker at Current Position (CGI\ffiK)


(82) (80) (96) (00) (00) (cO) (96) (00) (cO) (cO)
SAMPLE ORDERS ZBS

Marker at Current Position (CGI\ffiK - short format)


(82) (04) (96) (cO) (96) (cO)

Modify Path (GI\ITITI)


@8) (06) (06) (cO) (01) (cO) (cO) (cO)

No-Operation (GNOH )
(cO)

Outline Path (GOPITI)


@4) (06) (cO) (cO) (01) (cO) (cO) (00)

Partial Arc at Given Position (GPARC)


a]3)(ic) (20) (cO) (00) (cO) (20) (00) (cO) too) (64) tco) (00) (00) t64) too)
(00) (cO) (cO) (cO) (40) (cO) (00) (00) (20) (cO) (00) (cO) (40) (00)

Partial Arc at Given Position (GPARC - short format)


aE3) (12) (20) (cO) (20) (cO) (64) (00) (64) (cO) (00) (40) (00) (00) (20) (00)
(00) (cO) (40) (00)

Partial Arc at Current Position (GCPARC)


(A3) (14) (64) (00) (00) (00) (64) (00) (00) (00) (00) (cO) (40) (00) (00) (00)
(20) (00) (00) (00) (40) (cO)

Partial Arc at Current Position (GCPARC - short format)


(A3)(OE) (64) (00) (64) (00) (00) (40) (00) (cO) (20) (00) (00) (00) (40) (00)

Pop (Glrop)
(3F) (cO)

Relative Line at Given Position (GRLINE)


0]1) (18) (50) (00) (00) (00) (50) (00) (cO) (cO) qA) (00) (00) (00) (64) (00)
(00) (00) GA) (00) (00) (00) (50) (00) (00) (cO)

Relative Line at Given Position (GRLINE - short format)


all)(Oc) (50) (cO) (50) (cO) GTA) (00) (64) (cO) qA) (cO) (50) (00)

Relative Line at Current Position (GCRLINE)


(Ai) (io) qA) (00) (00) (cO) (64) (00) (00) (cO) aIA) (cO) (00) (00) (50) (00)
(cO) (cO)

Relative Line at Current Position (GCRLINE short format)


(A1) (08) GA) (00) (64) (00) GA) (00) (50) (00)
290 OS/2 PRESENTATION MANAGER GPI

Set Arc Parameters (GSAP)


(22) (10) (02) (00) (00) (cO) (02) (00) (cO) (cO) (00) (cO) (00) (00) (cO) (00)
(cO) (cO)

Set Arc Parameters (GSAP - short format)


(22) (08) (02) (cO) (02) (cO) (cO) (cO) (cO) (cO)

Push and Set Arc Parameters (GPSAP)


(62) (10) (02) (cO) (00) (cO) (02) (00) (cO) (cO) (00) (cO) (cO) (00) (cO) (cO)
(cO) (cO)

Push and Set Arc Parameters (GPSAP - short format)


(62) (08) (02) (cO) (02) (cO) (cO) (00) (cO) (cO)

Set Background Color (GSBCOL)


(25) (02) (01) (cO)

Push and Set Background Color (GPSBCOL)


(65) (02) (01) (00)

Set Background Indexed Color (GSBICOL)


(A7) (04) (cO) (06) (00) (cO)

Push and Set Background Indexed Color (GPSBICOL)


a]7) (04) (cO) (06> too) (00)

Set Background Mix (GSBI\fl[)


(OD) (02)

Push and Set Background Mix (GPSBMX)


(4D) (02)

Set Character Angle (GSCA)


(34) (08) (02) (cO) (00) (cO) (01) (00) (00) (cO)

Set Character Angle (GSCA - short format)


(34) (04) (02) (00) (01) (cO)

Push and Set Character Angle (GPSCA)


(74) (08) (02) (cO) (00) (cO) (01) (00) (cO) (cO)

Push and Set Character Angle (GPSCA - short format)


(74) (04) (02) (cO) (01) (00)
SAMPLE ORDERS Z91

Set Character Cell (GSCC)


(33) (OE) (32) (cO) (00) (cO) (32) (00) (cO) (cO) (00) (cO) (cO) (00) (80) (00)

Set Character Cell (GSCC - short format)


(33) (OA) (32) (cO) (32) (cO) (cO) (00) (cO) (cO) (80) (cO)

fish and Set Character Cell (GPSCC)


(03) (OE) (32) (00) (00) (cO) (32) (00) (cO) (cO) (00) (cO) (cO) (00) (80) (00)

Push and Set Character Cell (GPSCC - short format)


(03) (OA) (32) (cO) (32) (cO) (cO) (00) (cO) (cO) (80) (cO)

Set Character Direction (GSCD)


(3A) (01)

Push and Set Character Direction (GPSDC)


(7A) (01)

Set Character Precision (GSCR)


(39) (01)

Push and Set Character FTecision (GPSCR)


(79) (01)

Set Character Set (GSCS)


(38) (00)

fish and Set Character Set (GPSCS)


(78) (00)

Set Character Shear (GSCH)


(35) (08) (01) (00) (00) (00) (05) (00) (cO) (cO)

Set Character Shear (GSCH -short format)


(35) (04) (01) (00) (05) (00)

Push and Set Character Shear (GPSCH)


(75) (08) (01) (00) (00) (00) (05) (00) (00) (cO)

Push and Set Character Shear (GPSCH - short format)


(75) (04) (01) (00) (05) (00)

Set Clip Path (GSCPITI)


@4) (06) (04) (cO) (01) (00) (cO) (00)
292 OS/2 PRESENTATION MANAGER GPI

Set Color (GSCOL)


(OA) (01)

fish and Set Color (GPSCOL)


(4A) (01)

Set Current Position (GSCP)


(21) (08) (32) (cO) (00) (cO) (64) (cO) (cO) (cO)

Set Current Position (GSCP - short format)


(21) (04) (32) (cO) (64) (cO)

fish and Set Current Position (GPSCP)


(61) (08) (32) (cO) (00) (cO) (64) (cO) (cO) (cO)

Push and Set Current Position (GPSCP - short format)


(61) (04) (32) (cO) (64) (cO)

Set Extended Color (GSECOL)


(26) (02) (01) (00)

fish and Set Extended Color (GPSECOL)


(66) (02) (01) (00)

Set Fractional Line Width (GSFLW)


(11) (02) (cO) (01)

fish and Set Fractional Line Width (GPSFLW)


(51) (02) (cO) (01)

Set Indexed Color (GSICOL)


(A6) (04) (cO) (01) (00) (cO)

fish and Set Indexed Color (GPSICOL)


a]6) (04) (cO) (01) (00) (cO)

Set Individual Attribute (GSIA)


(14) (06) (01) (01) (00) (01) (cO) (00)

Push and Set Individual Attribute (GPSIA)


(54) (06) (01) (01) (00) (01) (cO) (00)

Set Line End (GSLE)


(1A) (01)
SAMPLE ORDERS 293

fish and Set Line End (GPsuE)


(5A) (01)

Set Line Join (GSIJ)


(18) (01)

Push and Set Line Join (GPSIJ)


(58) (01)

Set Line type (GSLT)


(18) (01)

Push and Set Line Ttre (GPSLT)


(58) (01)

Set Line Width (GSLW)


(19) (01)

fish and Set Line Width (GSFLW)


(59) (01)

Set Marker Cell (GSMC)


(37) (OA) (32) (cO) (00) (cO) (32) (00) (00) (cO) (80) (00)

Set Marker Cell (GSMC - short format)


(37) (06) (32) (cO) (32) (cO) (80) (00)

Push and Set Marker Cell (GPSMC)


(77) (OA) (32) (00) (00) (cO) (32) (00) (cO) (00) (80) (cO)

Push and Set Marker Cell (GPSMC - short format)


(77) (06) (32) (cO) (32) (00) (80) (00)

Set Marker Set (GSMS)


(3C) (cO)

Push and Set Marker Set (GPSMS)


(7C) (cO)

Set Marker Symbol (GSMT)


(29) (01)

Push and Set Marker Symbol (GPSI\IT)


(69) (01)
294 OS/2 PRESENTATION MANAGER GPI

Set Mix (GsnK)


(OC) (02)

fish and Set Mix (GPSMX)


(4C) (02)

Set Model Thansform (GSTM)


(24) (1C) (cO) (01) (CC) (OC) (cO) (00) (02) (cO) (cO) (cO) (cO) (00) (00) (00)
(cO) (cO) (cO) (cO) (02) (cO) (14) (00) (cO) (cO) (14) (cO) (cO) (00)

Set Model 'Thansform (GSTM - short format)


(24) (10) (cO) (01) (CC) (OC) (cO) (02) (cO) (cO) (cO) (cO) (00) (02) (14) (00)
(14) (cO)

fish and Set Model Thansform (GPSTM)


(64) (1C) (cO) (01) (CC) (OC) (cO) (00) (02) (00) (00) (cO) (cO) (00) (00) (00)
(cO) (cO) (cO) (cO) (02) (cO) (14) (00) (cO) (cO) (14) (00) (cO) (00)

Push and Set Model 'Thansform (GPSTM - short format)


(64) (10) (00) (01) (CC) (OC) (00) (02) (cO) (cO) (00) (00) (00) (02) (14) (00)
(14) (00)

Set Pattern Reference Point (GSPRP)


(AO)(OA) (cO) (00) (00) (00) (cO) (00) (cO) (cO) (00) (00)

Set Pattern Reference Point (GSPRP - short format)


(AO) (06) (cO) (00) (00) (00) (00) (00)

Push and Set Pattern Reference Point (GPSPRP)


a3io)(OA) (cO) too) (00) (00) (cO) (00> (cO) (cO) (00) (00)

Push and Set Pattern Reference Point (GPSPRP - short format)


G]0) (06) (cO) (cO) (00) (co) (co) (oo)

Set Pattern Set (GSPS)


(08) (cO)

fish and Set Pattern Set (GPSPS)


(48) (cO)

Set Pattern Symbol (GSPI`)


(28) (08)
SAMPLE ORDERS 295

fish and Set Pattern Symbol (GPSPT)


(09) (08)

Set Pick Identifier (GSPIK)


(43) (04) (02) (cO) (00) (cO)

rush and Set Hck Identifier (GPSPIK)


(23) (04) (02) (cO) (00) (cO)

Set Stroke Line Width (GSSLW)


(15) (06) (cO) (cO) (80) (cO) (cO) (00)

Set Stroke Line Width (GSSLW -short format)


(15) (04) (cO) (cO) (80) (cO)

fish and Set Stroke Line Width (GPSSLW)


(55) (06) (cO) (00) (80) (cO) (00) (00)

Push and Set Stroke Line Width (GPSSLW -short format)


(55) (04) (cO) (00) (80) (00)

Set Viewing Thansform (GSTV)


(31) (1C) (00) (00) (CC) (OC) (00) (00) (02) (00) (00) (00) (00) (00) (00) (00)
(00) (00) (00) (00) (02) (00) (00) (00) (00) (00) (00) (cO) (00) (00)

Set Viewing 'Thansform (rTSTV - short format)


(31) (10) (00) (cO) (CC) (OC) (cO) (02) (cO) (cO) (00) (00) (00) (02) (00) (00)
(cO) (cO)

Set Viewing Window (GSVW)


(27) (12) (80) (3C) (00) (00) (00) (00) (20) (03) (00) (cO) (00) (00) (00) (00)
(20) (03) (cO) (00)

Set Viewing Window (GSVW - short format)


(27) (OA) (80) (3C) (00) (00) (20) (03) (00) (cO) (20) (03)

Sharp Fillet at Current Position (GCSFLT)


296 OS/2 PRESENTATION MANAGER GPI

Sharp Fillet at Current Position (GCSFIJI`) (continued)


(cO) (cO) (cO) (80) (00) (cO) (cO) (40) (cO) (cO) (cO) (30) (cO)
(cO) (cO) (cO) (08) (00) (cO) (cO) (04) (cO) (cO) (00) (02) (cO)
(cO) (cO)

Sharp Fillet at Current Position (GCSFLT - short format)


APPENDIX 6

GPI Functions Supported only by a Normallps

The following functions are invalid for a Micro-PS.


GpiAssociate
GpiBeginElement
GpicallsegmentMatrix
Gpiclosesegment
GpicorTelatechain
GpicorTelateFrom
Gpicorrelatesegment
GpiDeleteElement
GpiDeleteElementRange
GpiDeleteElementsBetweenLabels
GpiDeletesegment
GpiDeletesegments
GpiDrawchain
GpiDrawDynanics
GpiDrawFrom
GpiDrawsegment
GpiElement

297
298 OS/2 PRESENTATION MANAGER GPI

GpiEndElement
GpiErrorsegmentData
GpiGetData
GpiLabel
GpioffsetElementpointer
Gpiopensegment
Gpipop
GpiputData
GpiQueryAttrMode
GpiQueryDeITag
GpiQueryDrawcontrol
GpiQueryDrawingMode
GpiQueryEditMode
GpiQueryElement
GpiQueryElementpointer
GpiQueryElementType
GpiQuerylnitialsegmentAttrs
GpiQuerysegmentAttrs
GpiQuerysegmentNames
GpiQuerysegmentHriority
GpiQuerysegmentThansform.Matrix
GpiQuerystopDraw
GpiQueryTag
GpiQueryviewingThansformMatrix
GpiRemoveDynamics
GpisetAttrMode
GpisetDeITag
GpisetDrawc.ontrol
GpisetDrawingMode
GpisetEditMode
GpisetElementpointer
Gpl FUNaloNs suppORTED ONLy By A NORMAL-ps T99

GpisetElementpointerAtLabel
GpisetlnitialsegmentAttrs
GpisetsegmentAttrs
GpisetsegmentHriority
GpisetsegmentThansform.Matrix
GpisetstopDraw
GpisetTag
Gpisetviewin.g'ThansformMatrix
Note that GpisetDrawcontrovGpiQueryDrawcontrol are valid in a Micro-PS for
the DCTL_DISPLAY, DCTL_BOUNDARY, DCTL_CORRELATE controls only.
References and Bibliography

IBM Operatirig System/ 2 Version 1.2 Programming Tloozs cnd, Irrformation: Presen-
tation MCLrager Programming Roference. T989.

IBM Operating System/ 2 Version 1.3 Programming Tlools cnd, Irrformation: TlechTti-
cal Update. ±990.

IBM Operating System/2 Version 1.2 Programming Guide. T989.

IBM Graphics Obj ect Coriterit Architecture Roferenee (SC8±-6804).

IBM Mined, Obj ect Dooumerit Corttent Archi±ectwre Reference (SC82-680Z).

IBM Reference Iriformation for Pi,cture Iritercha;nge Format (SCE53-02,44).

Kogan, M.S. OS/2 2.a 32-8££ APT. IBM Personal Systems Developer. Spring 1990.
pp. 23-30.

Kogan, M.S. and Tycast, R. OS/2 2. 0 TooZs and Program Dez/ezapmeJ}£. IBM Personal
Systems Developer. Spring 1990. pp. 31-35.

Microsoft OpercLin8 System/ 2 Programmers Roferenee. Microsrfu I+ess Vcr:urmes


1-3. 1989.

Microsoft Operating System/ 2 Programmers Reference. Microsoft Press Voha:rrLe 4.


1990.

300
Glossary

alternate mode. A mode used for defining which area segments formed by mul-
tiple overlapping closed figures are considered paid of the area interior. In alter-
nate mode a figure segment is considered part of the area interior if, counting from
infinity to a point in the segment, the number of figure boundary line crossings is
odd.
arbitrary page units. Page units that cause the PS page dimensions to be scaled
to fit the available device output area causing the picture to be displayed as large
as possible while retaining its correct aspect ratio.
arc parameters. A drawing attribute that maps a unit circle to the required
ellipse, controlling the shape and size of arcs drawn using GpiFullArc,
GpipartialArc, and the shape only of GpipointArc.
area bundle. A drawing or default attribute bundle structure containing the
group of attributes used for area fill operations.
apect ratio. The width to height ratio of a picture or shape.

association. A process by which a device contelit is linked to a presentation space


in order to identify the target output device for that presentation space.
attribute mode. A PS mode that enables the current value of a drawing attribute
to be automatically saved in a LIFO stack when a new value is set, and subse-
quently restored using a pop operation.
average character width. The average character width of a font in world coor-
dinates.
background color attribute. A picture attribute defining the background color
to be used by subsequent drawing primitives. Background color is a global attri-
bute.
background mix. A picture attribute defining the background mix mode to be
used by subsequent drawing primitives. Background mix is a global attribute.

301
302 OS/2 PRESENTATION MANAGER GPI

baseline. A reference line along which characters are positioned horizontally.

BitBlt. A Bit Block Thansfer operation that enables the rapid transfer of a rectan-
gular block of pixel image data between a bitmap and raster device.
bitmap. A rectangular array of pixel image data stored in memory that can be
used as the target of any output drawing operation (including BitBlt) or the source
of a BitBlt operation.
boundary accumulation. A process by which the coordinates of the smallest
rectangle into which the entire picture will fit, are accumulated in model space.
bundle. A drawing or default attribute structure containing the group of attri-
butes used for one particular type of primitive drawing operation (i.e., characters,
lines, areas, markers, or imaggBitBlt).
cached Micro-PS. An associated Micro-PS/WindowDC pair for use by applica-
tions where the large number of windows make it impractical to allocate a
separate Micro-PS and DC for each window.
chained segment. A root segment with its chained segment attribute set and
that forms part of the picture chain.
character angle attribute. A character bundle picture attribute defining the
baseline angle for outline and mode two raster font characters. This affects the
position and orientation of outline font characters and the position of mode two
raster font characters.
character box attribute. A character bundle picture attribute controlling the
height and width of outline font characters and the spacing of outline and mode
two raster font characters.
character bundle. A drawing or default attribute structure containing the group
of attributes used by character drawing primitives.
character cell. Synonym for character box.

character direction attribute. A character bundle picture attribute defining


the direction (left to right, right to left, top to bottom, or bottom to top) of outline
and mode two raster characters.
character mode attribute. A character bundle picture attribute specifying the
mode or precision with which characters should be drawn in terms of which
character ®ox, shear, and angle) attributes must be honored for raster font
characters, and which are optional, and whether or not and the font must be an
outline font.
character precision. Synonym for character mode.

character set. A character bundle picture attribute defining the id of the font to
be used for drawing characters.
G[OSSAR y 303

character shear attribute. A character bundle picture attribute defining the


shear angle of outline and mode two raster characters. This affects the position
and shape of outline font characters and the position of mode two raster font
characters (drawn vertically using the top to bottom or bottom to top character
direction attribute).
clip path. A path that has been converted to a clip path using Gpisetclippath to
define a complex clipping shape. Although paths are defined in world coordinates,
the clip path is frozen in device coordinates at the time of the conversion from a
path to a clip path.
clip region. A PS environment attribute used for clipping to a complex shape
defined by one or more rectangles in device coordinates.
clipping. A process by which all output that is outside a defined clip boundary is
removed (or clipped) and only that inside the clip boundary is displayed.
codepage. A mapping between a set of codepoints and a set of graphic characters.

color attribute. A picture attribute defining the foreground color to be used by


subsequent drawing primitives. Color is a global attribute.
color table. See logical color table.

correlation. A process by which drawing primitives are compared for intersection


against a rectangular pick aperture for the purpose of determining which primi-
tive or primitive group in a picture is at a given position on the display. This is
normally used to identify the primitive or primitive group selected by a user (e.g.,
using a mouse and pointer).
cosmetic line width. A line bundle picture attribute defining the thickness of
subsequent lines. Cosmetic line width consists of an integer and fractional paid
defining a multiplier to be applied to a line of unit thickness (e.g., one pel).
CSD. Corrective Service Diskette.

current position. A picture attribute defining the current drawing position in


world coordinates for a number of GPI output functions. Current position is
updated by most output functions.
default attribute. An attribute defining the actual attribute value to be used for
drawing when the coITesponding drawing attribute is specified as default.
default page coordinate space. A coordinate space immediately above the PS
page representing the picture defined in page coordinates without any scaling or
scrolling applied ®y the default viewing transform.).
default viewing transform matrix. A PS environment attribute providing a
transformation from default page coordinate space to the PS page and used for
scaling and scrolling the entire picture.
304 OS/2 PRESENTATION MANAGER GPI

detectable segment. A segment with its detectable segment attribute set mak-
ing it eligible for returning a hit from a retained correlation operation.
device context (DC). A logical output device defining the target of drawing
operations. A device context typically identifies a display window, an instance of a
shared output device such as a printer, a bitmap, or a virtual output device such
as a MetaFile.
device coordinate space. The coordinate space of the device.

device coordinates. Coordinates specified in device units, normally pels.

device drawing context (DDC). That part of the device context data owned by
the Hresentation Driver.
device driver interface (DDI). The presentation driver interface.

device transform. A transfo]rm from the PS page to device space that, together
with the device resolution, provides the required page units in the page. Device
transformi can be viewed as a PS environment attribute rather than a drawing
attribute (although it is, in fact, actually owned by the device rather than the PS).
direct DC. A device context used for direct printing.

direct printing. Output to a hard copy device that is passed directly to the device
for immediate output, bypassing the print queue and spooler.
disassociation. A process by which a presentation space and device contezit
association is broken.
display driver. A Pkesentation Driver used to output to the display device.

dithering. A process by which RGB colors that are not available on the device are
simulated by alternating the colors used for different pels when drawing an area.
draw controls. A selection of modal PS options that control subsequent drawing
operations (i.e., erase before draw, display, enable boundary accumulation, draw
dynamics, enable correlation).
drawing attribute. A picture attribute that controls the appearance (e.g., color)
of subsequent drawing primitives and may be varied during drawing for picture
constmction.
drawing mode. A PS mode controlling whether output primitives are drawn,
accumulated in retained segments, or both.
drawing order. A sequence of bytes used for representing a drawing primitive or
attribute in a retained graphics or MetaFile segment. An order is the smallest unit
of an element.
drawing primitive. A picture function that produces output to a device.
G[OSSAR y 305

dynamic segment. A chained segment with its dynamic segment attribute set
that can be rapidly drawn and removed using XOR mix mode without affecting the
picture beneath it.
DRIVDATA. A structure containing device dependant driver data (such as device
type, printer, and job properties) required when opening a printer DC.
element. A group of one one more related drawing orders in a retained segment
or MetaFile, typically generated by a single GPI function call, and treated as a
single entity addressed by the element pointer for segment editing purposes.
element pointer. An element offset used to identify the target element or ele-
ments of a retained segment editing operation.
em height. The height of the em square representing the font point size in world
coordinates. For an outline font, this is the same as the height of the character box
attribute.
em inc. The width of the em square in world coordinates. For an outline font, this
is the same as the width of the character box attribute.
em square. A square of size equivalent to the font point size in world coordinates.

environment and resource functions. The collection of environment attri-


butes and resources (e.g., color tables, fonts) owned by the presentation space.
Apart from incremental loading of resources as required, these should remain
constant during drawing.
environment attribute. A presentation space attribute (e.g., default view ma-
trix) that controls the appearance of the entire picture. PS environment attributes
should not be varied during drawing for picture construction.
external leading. The maximum vertical font spacing in world coordinates that
can be added to the maximum baseline extent without affecting the pleasing
appearance of the text.
face name. The full typeface name for a font (e.g., "Courier Bold Italic"). Fonts
within a single font file will frequently have different face names.
family name. A name similar to the face name but more general (e.g., "Courier"
is the equivalent family name of face name ``Courier Bold"). Fonts within a single
font file will normally have a common family name.
fast chaining. A segment attribute providing a performance hint to the system
that optionally allows the system to omit the drawing attribute reset that would
otherwise occur at the start of each new root segment. Note that fast chaining does
not guarantee that no reset will be performed.
font. A collection character glyphs or symbols defining the character shapes for a
particular typeface required by one or more codepages.
font metrics. A collection of parameters describing the attributes of a font.
306 OS/2 PRESENTATION MANAGER GPI

geometric line width attribute. A line bundle picture attribute defining the
thickness of geometric wide lines created using GpiModifypath or Gpistrokepath.
geometric wide line. A line with thickness specified in world coordinates and
scaled using the GPI transforms. The line interior is filled using an area fill
pattern. Geometric wide lines are constructed using the path functions.
global attribute. A bundle attribute (i.e., color, mix, background color, or back-
ground mix) that occurs in multiple attribute bundles and can be set in all bundles
simultaneously using a single function call (e.g., Gpisetcolor).
91yph. A graphic symbol typically representing a single font character.

GPI. Graphics Programming Interface.

graphics engine. The component that, together with the device drivers, im-
plements the GPI graphics drawing algorithms.
graphics field. A PS environment drawing attribute that defines a clipping rec-
tangle in the PS page.
graphics segment. A graphics ob].ect containing a group of related elements (or
drawing orders).
image. A rectangular array of pixel data.

image bundle. A drawing or default attribute structure containing the group of


attributes used by image and BitBlt drawing primitives.
index mode. A color table mode in which colors are specified as index values
referencing corresponding RGB values in the color table.
Info DC. A device context used only for querying information about the device.

information context. See Info DC.

INI file. A file (e.g., OS2.INI, OS2SYS.INI) managed by the system and used to
store application and system profile information (e.g., printer properties).
instancetransform.A model transform attribute specified with
GpicallsegmentMatrix.
internal leading. A vertical distance in world coordinates equal to the difference
between the maximum baseline extent and the em height.
internal segment prolog. A segment prolog located before the first element of a
segment, used intemally to store the segment transfo]rm and viewing transform
and not directly visible to an application.
kerning. A process by which the spacing between certain pairs of characters (e.g.,
To) in a proportional font is adjusted such that the character boxes overlap to
provide a further improvement in the appearance of text.
G LOssARy Sow

lcid. I.ocally coded identifier (synonym for set id).

line bundle. A drawing or default attribute structure containing the group of


attributes used by line drawing primitives.
line end attribute. A line bundle picture attribute defining the shape to be used
for the ends of geometric wide lines created using GpiModifypath or
Gpistrokepath.
line join attribute. A line bundle picture attribute defining the shape to be used
for the joins in geometric wide lines created using GpiModifypath or
Gpistrokepath.
line type attribute. A line bundle picture attribute defining the style (e.g., dot-
ted, solid) of subsequent lines.
line width attribute. A line bundle picture attribute defining the cosmetic line
width of subsequent lines.
logical color table. A map of index to RGB color values where the index value
may be used as a color attribute.
logical font. A collection of font attributes describing the characteristics of a
required font.
lower case ascent. The maximum distance that a lower case character of the font
ascends above the baseline in world coordinates.
lower case descent. The maximum distance that a lower case character of the
font descends below the baseline in world coordinates.
marker.A stand alone symbol positioned by its center and typically used to
represent a point on a graph.
marker box attribute. A marker bundle picture attribute defining the size of
outline markers drawn using an outline font or marker set.
marker bundle. A drawing or default attribute structure containing the group of
attributes used by marker drawing primitives.
marker cell. Synonym for marker box.

marker set. A marker bundle picture attribute defining the id of the marker set
or font to be used for drawing markers.
marker symbol. A marker bundle picture attribute defining the marker or font
codepoint to be used for drawing markers.
maximum ascender. The maximum distance that a font character ascends above
the baseline in world coordinates.
maximum baseline extent. The maximum vertical extent of font characters in
308 OS/2 PRESENTATION MANAGER GPI

world coordinates determined by the sum of the lnaximum ascender plus the
maximum descender.
maximum character increment. The maximum horizontal character incre-
ment of a font in world coordinates. For a universal font, this represents the
maximum for the font rather than the maximuln for a particular codepage.
maximum descender. The maximum distance that a character in the font de-
scends below the baseline in world coordinates.
Memory DC. A device contelit into which a bitmap may be selected in order to use
thebitmapasthesourceortargetofaBitBltoperationorthetargetofanydrawing
operation.
MetaFile. A picture interchange file in architected SAA format held as a disk file
or in memory as a memory MetaFile.
MetaFile DC. A device context used for recording a MetaFile.

Micro-PS. A presentation space that requires less memory and provides reduced
function compared to a Normal-PS.
mix attribute. A picture attribute defining the foreground mix mode to be used
by subsequent drawing primitives. Mix is a global attribute.
mix mode. A mode defining the logical operation used to combine new output with
the existing color of the pels at the drawing position to produce the final output.
model space. A conceptual coordinate space between world and page coordinates
in which the picture is constructed by the output of the model transfo]rm matrix.
model transform matrix. A drawing attribute that defines a transformation
from world coordinate space to model space and is intended for picture modeling
purposes.
monospaced font. A font in which equal spacing is used for all characters.

non-retained graphics. Graphics output primitives and attributes that are im-
mediately drawn and then discarded.
Normal-PS. A full presentation space capable of supporting all GPI functions.

outline font. A font in which the shape of each character is defined by a sequence
of vector strokes and curves defining a closed figure that is optionally filled.
page coordinate space. A conceptual coordinate space immediately above de-
vice space in which the picture is constructed by the output of the default viewing
transform matrix.
page units. Application defined coordinates of the PS page.

page viewport. A rectangle in device coordinates which, together with the PS


GLOSSARy 309

page dimensions, defines the device transfo]rm matrix. The page viewpord repre-
sents the area of the output device in which the PS page is displayed and it is
neither a clipping rectangle nor the same as the window rectangle on a display.
path. An object defined in world coordinates by a sequence of drawing primitive
and attribute functions issued between GpiBeginpath and GpiEndpath. A path
can be used for defining a filled area, a complex clipping shape, an outline, and for
drawing geometric wide lines.
pattern attribute. An area bundle picture attribute defining the fill pattern or
font codepoint to be used for area fill operations. This attribute is ignored for
bitmaps that are used as area fill patterns.
pattern reference point. An area bundle picture attribute defining the pattern
origin to be used for area fill operations.
pattern set attribute. An area bundle picture attribute defining the pattern set,
font, or bitmap id to be used for area fill operations.
pel. A picture element representing the smallest addressable point of a raster
device.
PIF. Picture Interchange File (an earlier IBM picture interchange architecture
standard similar to the MetaFile architecture).
pick aperture. A rectangle against which drawing primitives are compared for a
correlation hit.
picture functions. Drawing primitives and attribute functions that may be var-
ied during drawing for picture construction purposes.
pixel. Synonym for pel.

print queue. The queue used by the spooler for queued print jobs.

print queue processor. The component responsible for directly outputting a


dequeued print job to the appropriate device and applying any queue processor
parameters.
point. A unit of 1/72 inches used in printing.

point size. A measure of font character height in points. The point size is not
defined in terms of any measurable characteristic of a visible character.
presentation driver. A Hesentation Manager. device driver that converts the
graphics functions presented at the Device Driver Interface (DDI) into low level
OSA Kernel Device Driver requests or, in the case of a certain adapters (such as
displays), interfaces directly with the adapter hardware.
presentation space (PS). The object that owns the device independent resources
and environment attributes and that can optionally be used to store or retain a
complete graphics picture.
310 OS/2 PRESENTATION MANAGER GPI

proportional font. A font in which the characters are spaced according to the
widths of the individual characters in order to improve appearance.
psychometric RGB. A system by which increased RGB value yields a visually
linear increase in intensity rather than one based on photon intensity.
PS page. The presentation space page. This is a coordinate space with application
defined coordinates in which an application may define a picture in device inde-
pendent coordinates.
PS size. The dimensions of the presentation space page. These dimensions repre-
sent the area in page coordinates space that is displayed in the page viewport on
the output device.
queue processor. See print queue processor.

queued DC. A device contezit used to print queued output via the spooler.

queued printing. Output to a hard copy device that is enqueued on a print queue
for printing in sequence with other print jobs using the spooler.
raster font. A font in which the shape of each individual character is defined by
a rectangular pixel image or bitmap.
realizable color table. A color table that may be realized by using the RGB color
table values to load the physical device palette in order to obtain the closest
possible match to the requested colors.
region. An object defined by one or more rectangles in device coordinates that can
be used for area fill or converted to a clip region.
retained graphics. A PS mode in which the entire graphics picture is stored as
a collection of chained and called graphics segments in the PS retained graphics
segment store for subsequent display and editing.
RGB color. A color defined by a one byte red, a one b}rfe blue, and a one byte green
value.
RGB mode. A color table mode in which colors are specified directly as RGB
values.
root segment. Synonym for chained segment.

rop code. A code defining the mix mode for a BitBlt operation. A BitBlt rop code
value defines a three way mix operation combining source, pattern, and target
original pixel values to produce a final target output value.
SAA. Systems Application Architecture (a common application architecture for
IBM systems).
segment attributes. The properties of a graphics segment that apply to the
GLOSSARY 311

whole segment (i.e., detectable, visible, chained, dynamic, fast chaining, propagate
detectability, propagate visibility).
segment id. A 4 byte segment identifier that must be equal to or greater than
zero. Segment identifiers other than zero must be unique within a retained
graphics picture or a MetaFile.
segment prolog. A group of orders terminated by an end prolog order located at
the start of a graphics segment that has its prolog segment attribute set. Segment
prologs are not supported by the GPI except in MetaFiles.
segment transform. A model transfo]rm stored in the internal prolog of a seg-
ment.
set id. An application defined identifier used to identify a bitmap as an area fill
pattern or a logical font as a character set, marker set, or area fill pattern.
soft font. A device (e.g., printer) font in a format that enables it to be stored on
and installed from a disk or diskette.
spooler. The component that handles printing of queued output via the print
queue.
tag. A drawing attribute that defines a value to be associated with a group of one
or more elements or drawing orders in a segment for the purpose of identifying the
position of a subsequent correlate hit.
translation. A transform.ation operation producing a positional change.

typeface. The name used to describe the appearance or style of a particular font
(e.g., Roman).
viewing limits. A drawing attribute that defines a clipping rectangle in model
Space.

viewing transform matrix. A drawing attribute that defines a transformation


from model space to default page coordinate space.
winding mode.A mode used for defining which area segments formed from
multiple overlapping closed figures are considered part of the area interior. In
winding mode figure, boundary lines drawn in one direction can be considered to
have a weight of +1 and those in the opposite direction a weight of -1. A figure
segment is considered to be part of the area interior if, counting from infinity to a
point in the segment, the net weight of the figure boundary line crossings is
non-zero.
world coordinates. The coordinate space in which an application specifies its
coordinates for drawing.
WYSIWYG. What-You-See-Is-What-You-Get (terminology used to describe consis-
tency between the appearance of the same output on two different devices such as
a display and printer).
312 OS/2 PRESENTATION MANAGER GPI

x device resolution. For a raster font, this is the horizontal resolution in pels-
per-inch of the device for which the font was designed. For an outline font, it is the
width of the em square rectangle in font definition space in which the font was
defined.
x height. The height above the baseline of lower case characters (excluding
ascenders) in world coordinates, typically represented by the height of lowercase
`x.,

y device resolution. For a raster font, this is the vertical resolution in pels-per-
inch of the device for which the font was designed. For an outline font, it is the
height of the em square rectangle in font definition space in which the font was
defined.
Index

Alternate mode area fill, 81 BitBit, 6, 85no9, horizontal spacing, 107, 110
Arc functions, see Curve functions BitBlt functions, 84-90 output, 6
Arc parameters, 76-78. See also Biinap: position recorded in MetaFile, 109
Non-bundle attributes changing ownership, 129, 132 vertical spacing, 106-107
Area, 6. See oiso Path area creation, 128, 131 Character angle attribute, 67
Area bundle, 6, 61, 79ngo data format, 130 Character box attr.ibute, 66rfe7, 110
Area drawing functions, 79nol data trzmsfer, 129 Character bundle, 6, 60nol, 65no9
Area fill using regions, 170 definition in resource file, 128 Character cell attribute, 66-67
Area primitives, 81 deletion, 129 Character direction attribute, 69
AREABUNDRE, see Area bundle drawing to, 131-132, 262 Character functions, 65-71
Associate option on Gpicreateps, 49 file format, 130-131 Character mode attribute, 66
Association, 2, 45 format conversion, 127, 129-130 Character precision attribute, 66
Attributes: modification by driver, 127 Characters, see Fonts
default, 7, 63", 199 ormership, 85ng6 Character set attribute, 66
drawing, 5no recording in MetaFile, 202 Character shear attribute, 68
querying, 64 selection, 129 Character string primitives, 70
resetting, 64no5 set id, 112 CHARBUNDIE, see Character
Attribute bundles, 5ng, 59ngl. See stretching and compression, 87, bundle
also Area bundle; Character 128 Char_Extra spacing, 70-71
bundle; Image bundle; Line supported formats, 126-127 Clip path, 94-96, 169
bundle; Marker bundle use as area fill pattern, 112 Clip region, 169-171
Attribute functions, 60no2 use with PM_QLSTD print Clipping, 168-171
Attribute mode, 62rfe3, 159 format, 234 Code pages, 111-112
ATrR_CIIAINED segment use with realizable color table, Color attribute:
attribute, 182 127, 147 area, 79
AITR_DETECTABLE segment Bitmap dimension functions, 131 area background, 79
attribute, 181, 192 Bold font simulation, 108 character, 65
AITR_DYNAMIC segment Boundary accumulation, 8-9, 194, character background, 65
attribute, 182, 185 199, 2cO image, 84
AITR_FASTCIIAIN segment Break_Extra spacing, 71 image background, 84
attribute, 182 Bundle, see Attribute bundles line, 71
ATI`R_PROP DETECTABLE BITMAPINFO, 129, 130 marker, 82
segment-attribute,182,192 BITMAPINFOHEADER, 129, 130 marker background, 82
AITR_PROP_VI S IBIE segment Color queries, 148
attribute, 182 Color table, See oiso I.ogical color
ATI`R_VISIBIE segment attribute, Cached Micro-PS, 2 table creation
182, 192 Character: default, 143-145

313
314 INDEX

index mode, 143, 146 Doslhintlob functions, 235 typeface, 106


option on GpiplayMetaFile, 198 DosHintQ functions, 235-236 with PM_qsTD print format, 233
realizable, 146, 147-148 Draw and retain mode, 180-181 Form code, 5
recording in MetaFile, 201, 203 Draw controls, 183-184 Form selection, 232
RGB mode, 143, 146 Draw mode, 180-181
standard, 143-145 Drawing modes, 180-181
Coordinate: DRIVDATA, 229-230, 231, 259-260
avoiding overdow, 158 Dynamic segments, 185-186 Geometric wide line athibutes,
format option on Gpicreateps, 9, 90L91
4849 Geometric wide lines, 93-94
limits 9, 157-158 Global attributes, 6, 60
of rectangle boundary, 10 Edit mode, 186-187 GPI graphics subsystem structure,
CoITelation, 9, 190-193 Element pointer, 186 1-2
Current position, 3. See oiso Elements, 176 GPI layer, 1-2
Non-bundle attributes Em Square, 107 GPI picture and
Curve functions, 71-78 Engine, graphics, 1-2 environment/resource model ,
Curve primitives, 73-75 Environment functions (of FS), 7no 7&
Emor: GpiAsscoiate, 45, 199, 201
display, 12 GpiBeginArea, 81
handling, 11-13 GpiBeginpath, 91
DC, see Device context . PRERR COORDINATE OVIRFL GpiBitBlt, 132
DCTL_BOUNDARY draw control, OW, 270 in retain mode, 7
184, 194 PRERR PATH LIMIT EXCEEDE parameters, 87no9
DCTL CORRELATE draw control, D, 81, 91 source and target combinations,
184, 190-191 PRERR PS BUSY, 10 85
DCTL DISPLAY draw control, 184 ret- codes, 11 with PM_QLSTD print format, 234
DCTL_DYNAMIC draw control, severity, 12 GpiBox, 75
184, 185 GpicallsegmentMatrix, 160, 176
DCTL_ERASE draw control, 184 Gpicharstring, 70
Default attribute functions, see GpicharstringAt, 70
Attributes , default Fast chaining, 182 Gpicharstringpos, 70
Default viewing transform, 6, 162, FIXED numbers, 10-11 GpicharstringposAt, 70
196 Font: Gpiclosesegment, 176
DevEscape, 5, 49-50, 203 Adobe Type 1, 99, 100, 101, 104 GpicombineRegion, see Regions
Device context, 2, 4143 device, 99, 109 Gpiconvert, 158
direct, 42 lEmHeight metric, 107 GpicoITelatechain, 191-193
display window, 4142 lEmlnc metric, 107 GpicomelateFrom, 191-193
info, 42 lExtemalLeading metric, 106-107 GpicoITelatesegment, 191-193
memory, 43 match number, 108, 203 GpicreateBitmap, 128, 131
ounership, 2 metrics, 104-107 Gpicreatel-ogcolorTable, 145-147
queued, 42 monospaced, 101 GpicreateljogFont, 107-109, 112
MetaFile, 42 outline, 101 Gpicreateps , 4749
Device drawing context, 2 private, 100-101 GpicreateRegion, see Regions
Device driver, 1-2. See also proportional, 101 GpiDeleteBitmap, 129
llresentation driver public, ionioi GpiDeleteElement, see Segment,
Device Driver Interface @DI), 1-2 raster, 101, 106 editing
Device independence, 152 recording in MetaFile, 109 GpiDeleteElementRange, see
Device resolution for font selection, scaling using character box, Segment, editing
109 109-110 GpiDeleteElementsBetweenLabels,
Device transform, 163-165 scaling (outline) to match raster, see Segment, editing
Device types valid for use with GPI, 110 GpiDeleteMetaFile, 195
1 selection, 106, 107 GpiDeletesegment, see Segment,
DevopenDC parameters, 257-262 selection indicators, 108 editing
DevpostDeviceModes, 229-230, setting horizontal pitch, 110 GpiDeletesegments, see Segment,
231, 232 setting point size using character editing
DevQuerycaps, 50 box, 110 GpiDeletesetld, 107, 112
DevQueryHardcopycaps, 5, 232 sources, 99 GpiDestroyps , 46
Direct printing, 219-220 sXDeviceRes metric, 106, 109-110 GpiDestroyRegion, see Regions
Dithering, 145 sYDeviceRes metric, 106, 109-110 GpiDrawchain, 179-180
DosFhint spooler API, 235-236 szFacename metric, 106 GpiDrawD3mamics, 185
DosHrintDest functions, 235 szFamilyname metric, 106 GpimawFrom, 179-180
INDEX 315

GpiDrawsegment, 179-180 GpiQuerycharDirection, see 158. See azso Non-bundle


GpiElement, 176 Character bundle attributes
GpiEndArea, 81 GpiQuerycharMode, see Character GpiQueryNearestcolor, 148
GpiEndpath, 91 bundle GpiQueryNumbersetlds, 109
GpiEqualRegion, see Regions GpiQuerycharset, see Character GpiQuerypageviewport, 164
GpiErase, 50 bundle GpiQuerypattem, see Area bundle
GpiEITorsegmentData, 13 GpiQuerycharshear, see Character GpiQuerypattemReffoint, see Area
GpiExcludeclipRectangle, see Clip bundle bundle
region GpiQuerycharstringpos, 70, 109 GpiQuerypattemset, see Area
GpiFillpath, 92 GpiQuerycharstringposAt, 70 bundle
GpiFuildrc, 73-74 GpiQueryclipBox, see Clip region Gpiquerypel, 79
GPIF SHORT coordinate format GpiQueryclipRegion, see Clip region GpiQueryFlckApertureposition, 191
option, 157 GpiQuerycolor, see Global attributes GpiQueryHckAperturesize, 190
GpiGetData, 175-176 GpiQuerycolorData, 148 GpiQueryRealcolors, 148
Gpilmage, 85 GpiQuerycolorlndex, 148 GpiQueryRegionBox, see Regions
GpilntersectclipRectangle, see Clip GpiQuerycp, 111 GpiQueryRegionRects, see Regions
region GpiQuerycurentposition, see GpiQueryRGBColor, 148
GpiLabel, 186 Non-bundle attributes GpiQuerysegmentAttrs, 181
GpiLine, 72 GpiQueryDefArcparams, see GpiQuerys egmentNames, see
GpilloadBitmap, 128, 132 Attributes, default Segment, editing
GpilloadFonts, 101 GpiQueryDefAttrs, see Attributes, GpiQuerysegmentlhiority, 180
GpilloadMetaFile, 195 default GpiQuerysegmentThansformMatrix,
GpiMarker, 84 GpiQueryDefaultviewMatrix, 162 160
GpiModifypath, 93-94 GpiQueryDeITag, see Attributes, GpiQuerysetlds, 109
GpiMove, 62no3. See oZso default GpiQueryTag, see Non-bundle
Non-bundle attributes GpiQueryDefviewingLimits, see attributes
GpioffsetElementpointer, see Attributes, default GpiQueryviewingLimits , see
Segment, editing GpiQueryDevice, 50 Non-bundle attributes
GpioffsetRegion, see Regions GpiQueryDeviceBitmapFormats, GpiQueryviewingThansformMatrix,
Gpiopensegment, 176 127 161. See also Non-bundle
Gpioutlinepath, 93 GpiQueryDrawcontrol, 183 attributes
GpipaintRegion, 7. See also GpiQueryEditMode, see Segment, GpicinerywidthTable, 101
Flegions editing GpiRealizecolorTable, 127, 147
GpipartialArc, 75 GpiQueryElement, 176 GpiRectlnRegion see Regions
GpiplayMetaFile, 196-199 GpiQueryElementpointer, see GpiRemoveDynamics, 185
Gpipointdrc, 75 Segment, editing GpiResetBoundaryData, 194
GpipolyFillet, 73 GpiQueryElementType, see GpiResetps, 50
GpipolyFilletsharp, 73 Segment, editing GpiRestoreps , 50-51
Gpipolylline, 72 GpiQueryFonts, 105, 108 Gpifrotate, 7
GpipolyMarker, 84 GpiQueryFontMetrics, 105 GpisaveMetaFile, 195
Gpipolyspline, 73 GpiQueryGraphicsField, 169 Gpisaveps, 50-51
Gpipop, see Attribute mode GpiQuerylnitialsegmentAttrs, 181 Gpiscale, 7
GpiltlnRegion, see Regions GpiQueryKemingpairs, 101 GpisetArcparams, see Non-bundle
GpifutData, 175-176 GpiQueryLineEnd, see Line bundie attributes
GpiQueryArcparams, see GpiQueryLineJoin, see Line bundle GpisetAttrs, 60
Non-bundle attributes GpiQueryLineType, see Line bundle GpisetAttrMode, see Attribute
GpiQueryAttrs, 60 GpiQueryLinewidth, see Line mode
GpiQueryAttrMode, see Attribute bundle GpisetBackcolor, see Global
mode GpiQueryljinewidthGeom, see I.ine attributes
GpiQueryBackcolor, see Global bundle GpisetBackMix, see Global
attributes GpiQueryljogcolorTable, 148 attributes
GpiQueryBackMix, see Global GpiQueryMarker, see Marker bundle GpisetBitmap, 129, 132
attributes GpiQueryMarkerBox, see Marker GpisetBitmapBits, 129
GpiQueryBitlnapBits, 129 bundle GpisetBitmapDimension, see
GpiQueryBitmapDimension, see GpiQueryMarkerset, see Marker Bitmap dimension functions
Bitmap dimension functions bundle GpisetBitmapld, 112
GpiQueryBoundaryData, 194 GpiQueryMetaFileBits, 196 GpisetcharAngle, see Character
GpiQuerycharAngle, see Character GpiQueryMetaFileLength, 196 bundle
bundle GpiQueryMix, see Global attributes GpisetcharBox, see Character
GpiQuerycharBox, see Character GpiQueryModel'Thansfo]mMatrix, bundle
bundle
316 INDEX

GpisetcharDirection, see Character with PM_Q_STD print format, Matoh number, see Font, Match
bundle 234 n-her
GpisetcharMode, see Character GpisetRegion, see Regions MATRIXIF srfucture, 157
bundle GpisetsegmentAttrs, 181 Matrix multiplication, 269-271
Gpisetcharset, see Character GpisetsegmentHiority, 180 Memory DC, 262
bundle GpisetsegmenThaLnsformMatrix, Memory MetaFile, 195
Gpisetcharshear, see Character 160 MetaFile, 195-218
bundle GpisetstopDraw, 10, 184-185 creation, 195
Gpisetclippath, 96 GpisetTag, 192. See azso differences from PM_GLS'ID
GpisetclipRegion, see Clip region Non-bundie athibutes format, 222
Gpisetcolor, see Global attributes Gpis etviewinglinits, see display as sub-picture, 2cO
Gpisetcp, 111 Non-bundle attributes escape orders, 200-203, 280-282
Gpisetcurrentposition, 62. See azso GpisetviewingThansformMatrix, interchange with other systems,
Non-bundle attributes 161, 2cO. See also Non-bundle 2cO
GpisetDefArcparans, see athibutes internal sthicture, 272T282
Attributes, default Gpi strokepath, 93L94 printing, 199, 204, 222
GpisetDefAttrs, see Attributes, GpiTh-late, 7 rules for creation, 200L-203
default GpiunrealizecolorTable, 147 SAA conforming, 2cO
GpisetDefaultviewMatrix, 162 GpiwcBitBlt, 89-90, 129, 132 sealing to fit output area, 199
GpisetDefrag, see Attributes, recording in another MetaFile,
default 199
Gpis etDeIviewingLimits , see IBIVI\TUIL print driver, 224 MetaFile functions, 195-199
Attributes, default Icon, 130-131 MicrcLFrs, 2, 49, 297-299
Gpisetmawcontrol, 183, 190 IMAGEBUNDIH, see Image bundle Mix mode attribute:
GpisetDrawingMode, 180-181 Image bundle, 6, 61, 84ng5 aea, 79
GpisetEditMode, see Segment, Image display, 132, 147 area background, 79
editing Image functions, 84no5 character, 65
Gpi s etElementpointer, see Image primitives, 85-90 character background, 66
Segment, editing Instance transform, 160 image, 85
Gpi s etElementpointerAtLabel , see Internal prolog, 62, 160, 161-162 image background, 85
Segment, editing Italic font simulation, 108 line, 71
GpisetGraphicsField, 5, 169 marker, 82
GpisetlnitialsegmentAttrs, 181 marker background, 83
GpisetllineEnd, see Line bundle Keming, 101-104 Mixed 32-bit and 16-bit
GpisetLineJoin, see Line bundle applications, 256
Gpisetl.ineType, see Line bundle Model transform, 6, 158-161. See
GpisetLinewidth, see Line bundle Leid, see Set id also Non-bundle attributes
GpisetLinewidthGeom, see Line Line bundle, 6, 58, 71-72. See azso Multi-threaded applications, 10
bundle Geometric wide line attributes
GpisetMarker, see Marker bundle Line end attribute, 90-91
GpisetMarkerBox, see Marker Line functions, 71-79 Network printing, 225-227
bundle Line join attribute, 91 Non-bundle attributes, 61no2
GpisetMarkerset, see Marker Line prinitives, 72 Non-retained graphics, 8
bundle Line type attribute, 71 Non-retained only functions, 7
GpisetMetaFileBits, 195-196 Line width attribute, 61, 71 Non-retained segments, 177, 183
GpisetMix, see Global attributes Line width geometric attribute, 90 Normal-PS, 2, 49
GpisetModelThansformMatrix, 158. LINEBUNDIE, see Line bundle
See also Non-bundle attr.ibutes lMatch, see Font, match number
Gpisetpageviewport, 154, 163-165 IJogical color table creation, 145-147 Order buffer, 175-176
during MetaFile recording, 201 Ijogical font creation, 107-109 Orders:
with PM_Q_STD print format, 234 drawing, 172-176, 283-296
Gpisetpattem, see Area bundle extended, 174-175
GpisetpattemRefpoint, see Area Marker box attribute, 83" fixed 1 byte, 172
bundle Marker bundle, 6, 61, 82" fixed 2 byte, 173
Gpisetpatteinset, see Area bundle Marker cell attribute, 83no4 long, 173-174
Gpisetpel, 79 Marker functions, 82ng4 0D_DIRECT DC, see Device
Gpisetpel, in retain mode 7 Marker primitives, 84 context, direct
GpisetHckApertureposition, 191 Marker set attribute, 83 OD_INFO DC, see Device context,
GpisetHckAperturesize, 190 Marker symbol attribute, 83 info
Gpisetrs, 46, 163 MARKERBUNDIE, see Marker OD_MEMORY DC, see Device
during MetaFile recording, 201 bundle context, memory
INDEX 317

OD_RETAFIIH DC, see Device device name, 219, 228-229 GpipartialAro, figs 3.9-3.10, 76,
context, MetaFile driver name, 229, 231 77
OD_METAFILE_NOQUERY DC , fonts, 234-235 keming, fig 4.2, 102-103
See Device context, MetaFile installation, 224 line drawing, fig 1.7, 26T27
OD_QUEUED DC, see Device job property selection dialog, logical color table creation, fig 6.2,
context, queued 229-230, 231 149
OSA Version 2.0, 255-256 output to, 3 logical font creation, figs 4.4rd.6,
port name, 229 112-118
property selection dialog, 230 marker drawing, fig 1.9, 30-31
Page dimensions 4, 4748, 154, queue name, 229, 230-231 MetaFile examples, figs
163-164 frinter pcoling, 225 11.1-11.7, 204-218
Page units, 34, 48, 153-154, ELter set up, 224-225 Micro-PS draw, figs 2.4-2.5, 54ng6
163-164 ELter sbaring, 225 Normal-rs draw, fig 2.3, 51i3
recording in MetaFile, 201 ELting, 2ig-254 outline font scaling, figs 4.84.11
setting on GpiplayMetaFile, 197 ASCII text, 219, 232 120-125
Page viewport, 163-165 direct, 219-220 printer info, querying from INI
Path areas, 92 display screen, 232 file, figs 12.4-12.6, 236T240,
Path definition, 91-92 MetaFiles, 199, 204, 222 figs 12.8-12.10, 244-245
Path outlines, 93 moncdrome, 265 printer, output to, fig 1.3, 14-17
Paths, 90-97 multiple copies, 263 printing raw data, fig 12.15,
Pattern origin attribute, 80 output area definition, 263 252-253
Pattern set attribute, 79, 112 queued, 220 printing to default queue, fig
Pattern symbol attribute, 80 raw data, 219, 228, 232 12.14, 249-251
Ficlchg function, 204 real size, 265 print queue processor querying,
Hck aperture, 190 scaled to fit, 264 fig 12.16, 254
Pick identifier, 192. See azso using base control program retained segment operations, fig
Non-bundle attributes functions, 220 9.2, 178, fig 9.4, 188
HCHint function, 204 using PM_Q_RAW format, 221, transformation, figs 1.11-1.13,
Hcture functions, 7 222 34ng
Picture function calls, 204 using PM_QLSTD format, scale to fit window, fig 7.5,
Picture utilities, 204 221-222, 233-234 166-167
PIF files, 204 using Hesentation Manager set id allocation, fig 4.7, 119
PM_Q_RAW print format, 221, 222, functions, 221-222, 227-232 sub-picture display, fig 11.7,
260 using printer selection method, 214-218
PM_qsTD print format, 221-222, 228-230, 232 text output, figs 1.4-1.6, 18-26
260 using queue selection method, translation removal, fig 7.6, 167
differences from MetaFile, 222 230-231, 232 window, output to, fig 1.2, 13-14
rules for creation, 233-234 using special formats, 222 WM_PAINT prcoessing, fig 2.7, 58
Point size of font, 98, 106 with zero translation, 165, Holog, see Internal prolog
Pointer, 128, 130-131 265-266 Psychometric RGB, 143, 147
I}resentation driver, 1-2, 222-223 PS, see I+esentation space
Hesentation space, 2, 4349 Hograns:
asscoiation, 45, 46, 49 area drawing, fig 1.8, 28-29 Queue destination functions, 235
cached Micro-PS, 43rd4, 4546 BitBlt, fig 1.10, 32-33, figs Queue driver, see Queue processor
creation, 44, 46 5.3-5.5, 135-139 Queue name, 219, 229, 230
Micro-PS, 43, 44 BitBlt image with realizable color Queue prcoessor, 232-233, 261,
Normal-PS, 43, 4445 table, fig 5.6, 139-142 263-266
ormership, 2 bitmap, create and draw to, fig Queue selection method of printing,
rmQueryHofilestring, 228, 229, 5.2, 133-134 230-231
230, 231, 233 cached Micro-PS draw, fig 2.6, 57 Queued printing, 220
frimitive groups, 5. See oiso clip path definition, fig 3.18,
Attribute bundles 96-97
frinitives, drawing, 5no DevpostDeviceModes, fig 12.7, Realizable color table, 132, 146,
Hint destination functions, 235 241, fig 12.12, 246 198-199
Hint job functions, 235 DRIVDATA querying for queue, Reference point, pattern, 80
Hint queue processor, see Queue fig 12.11, 245 Flegion complexity, 171
prcroessor emor display using Legion functions, 170
Hint requester, 225-227 WinGetLastError, fig 1.14, Flegions, 169-171
flint server, 225-227 38J0 Reset option on GpiplayMetaFile,
frint subsystem, 222-224 geometric wide line, fig 3.17, 197, 198, 234
Hinter, 219-254 95-96 Resource fLmctions of PS, 7
318 INDEX

Responsiveness to end user, 10 character, 66 TRANSFORM_ADD option, 156


Retain mode, 180-181 font creation, 107 TRANS FORM_PREEMFT option,
Retained graphics, 8 GpiplayMetaFile option, 197 156-157
Ret-codes, 11 marker, 83 TRANSFORM_REpljACE option,
RGB color, 143 pattern, 79 156
frop code, 87ng8 Spooler, disabling, 220
Rotation, see 'Thansformation, Spooler function calls, 222
rotation Stop draw, 184-185 Underscore font simulation, 108
Strikeout font simulation, 108
Sub-picture, drawing MetaFile as,
Scale-to-fit window, 165 200 Viewing limits, 168. See also
Scaling, 151 Sub-picture drawing using viewing Non-bundle attributes
Scaling, see 'Thansformation, scaling transform, 161 Viewing transformi 61, 62, 161-162,
Scrolling entire picture, 162 Suppress option on 196
Scrolling text, 4 GpiplayMetaFile, 197-198
Segment, 176-178 Symbol set, 204
attributes, 181-182 WinBeginpaint, 42, 45
called, 179 Winding mode area fill, 81
chained, 179 Tag, segment, 192-193 Window, output to, 3
content editing, 186-187 Text, 6. See also Fonts WinDraw functions, 7, 201
creation, 176-177 Text functions, 65-71 WinEndpaint, 45
editing, 187 Tezit output to display, 4 WinFreeErrorlnfo, 12
non-retained, 177, 183 Tezit output to printer, 4-5 WinGetclipps, 42, 45
priority, 180 Thransformation, See oZso 'Thansform WinGetErrorlnfo, 12
recording in MetaFile, 203 matrix, operation WinGetLastError, 12
retained, 177 about point, 152 WinGetps, 42, 45
structure, 177 pipeline, 154-155 WinGetscreenps, 42, 4546
unchained, 179 rotation, 6-7, 150-151 WinlJoadpointer, 128
zero id, 182-183 scaling, 7, 151, 162 WinopenwindowDC, 3, 41
Segment transform, 160-161 translation, 7, 151-152, 165 WinQuerywindowDC, 3, 41
Separator file, 227 'Thansform matrix: World coordinates, 152
Set id: operation, 267-271 WM_PAINT processing, 45
allocation, 109 order of concatenation, 154-155
bitmap, 112 parameter format, 157 32-bit OSA, 255-256

® .g8 gr
VNR Computer Library computer science/graphics

While 08/2 Presentation Manager offers a rich and powerful graphics interface, this complex
package is not generally well understood. In this volume, IBM's former GPI Development Team .
Leader for 08/2 1.1 clearly- describes the Graphics Programming Interface for the current
version of 08/2.

Designed to supplement the IBM and Microsoft ™ manuals, this guide addresses both GPI
and Device functions and their architectures. Graham C.E. Winn taps his extensive experience
with the GPI to show how it can provide high-quality text and graphics output to displays and
printers. He explains the full range of graphic functions from simple to complex, without use of
complicated mathematics.

Winn provides a detailed description of the Application Programming Interfaces, along with
more than 60 programming examples that help answer many questions about GP! and Device
functions. He covers use of the GP! to display text, characters, lines, curves, areas, markers,
images, and more. Chapters on all the facets of GPI drawing from an application expand your
understanding of:

• FontS'-public and private fonts, monospaced and proportional fonts, raster and outline
fonts, font selection, logical font creation
• BitmapS'-bitmap formats, creation, deletion, selection, data transfer
• Color tableS'-the standard color table, logical color table creation, color queries
■ Coordinate spaces and transformation-page units, matrix parameter formats, coordinate
limits, model transform , viewing transform, default viewing transform, device transform
• MetaFile5-MetaFile printing, MetaFile-to-MetaFile recording, scaling MetaFiles to fit an
output area, displaying a MetaFile as a subpicture, MetaFile restrictions
Printin5rqueued printing, base control program printing, Presentation Manager printing,
08/2 print subsystem, printer installation and setup, form selection, printer fonts

The author also explores the GPl's less obvious function capabilities, limitations, and restric-
tions. In addition, he helps clarify GPI operation through simple C programs that illustrate the
functions in use . The C programs may be purchased separately ~n a diskette.

Written by an IBM insider who has had extensive GP! involvement since its initial development,
this reference will open the door to superior 08/2 graphics and serve as a valuable aid to
application program developers.

ut D

Graham C.E. Winn, Ph.D., has worked at IBM since 1974 on display and workstation software in
both development and customer support roles. His involvement with Presentation Manager
began in 1986, when he became Lead GPI Developer for IBM's 0S/2 Version 1.1. He has
since worked as part of the team handling both service and non-defect questions relating to
GP! and other areas. Dr. Winn has also taught the GPI part of IBM's 0S/2 programming class
and presented a GPI seminar. He has written a number of journal art icles and technical dis-
closure bulletins, and holds a patent for a video display terminal with partitioned screen. He
earned his Ph.D. and B.Sc. degrees at Southampton University in England.

ISBN 0-442-00739-6
90000>
Van Nostrand Reinhold
115 Fifth Avenue, N.Y. , New York 10003

9 780442 007393

You might also like