.\" Automatically generated by Pod::Man 2.25 (Pod::Simple 3.16) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. \*(C+ will .\" give a nicer C++. Capital omega is used to do unbreakable dashes and .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, .\" nothing in troff, for use with C<>. .tr \(*W- .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is turned on, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .ie \nF \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . nr % 0 . rr F .\} .el \{\ . de IX .. .\} .\" .\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). .\" Fear. Run. Save yourself. No user-serviceable parts. . \" fudge factors for nroff and troff .if n \{\ . ds #H 0 . ds #V .8m . ds #F .3m . ds #[ \f1 . ds #] \fP .\} .if t \{\ . ds #H ((1u-(\\\\n(.fu%2u))*.13m) . ds #V .6m . ds #F 0 . ds #[ \& . ds #] \& .\} . \" simple accents for nroff and troff .if n \{\ . ds ' \& . ds ` \& . ds ^ \& . ds , \& . ds ~ ~ . ds / .\} .if t \{\ . ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" . ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' . ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' . ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' . ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' . ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' .\} . \" troff and (daisy-wheel) nroff accents .ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' .ds 8 \h'\*(#H'\(*b\h'-\*(#H' .ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] .ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' .ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' .ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] .ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] .ds ae a\h'-(\w'a'u*4/10)'e .ds Ae A\h'-(\w'A'u*4/10)'E . \" corrections for vroff .if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' .if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' . \" for low resolution devices (crt and lpr) .if \n(.H>23 .if \n(.V>19 \ \{\ . ds : e . ds 8 ss . ds o a . ds d- d\h'-1'\(ga . ds D- D\h'-1'\(hy . ds th \o'bp' . ds Th \o'LP' . ds ae ae . ds Ae AE .\} .rm #[ #] #H #V #F C .\" ======================================================================== .\" .IX Title "Prima::TextView 3" .TH Prima::TextView 3 "2009-02-24" "perl v5.14.2" "User Contributed Perl Documentation" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" Prima::TextView \- rich text browser widget .SH "DESCRIPTION" .IX Header "DESCRIPTION" Prima::TextView accepts blocks of formatted text, and provides basic functionality \- scrolling and user selection. The text strings are stored as one large text chunk, available by the \f(CW\*(C`::text\*(C'\fR and \f(CW\*(C`::textRef\*(C'\fR properties. A block of a formatted text is an array with fixed-length header and the following instructions. .PP A special package \f(CW\*(C`tb::\*(C'\fR provides the block constants and simple functions for text block access. .SS "Capabilities" .IX Subsection "Capabilities" Prima::TextView is mainly the text block functions and helpers. It provides function for wrapping text block, calculating block dimensions, drawing and converting coordinates from (X,Y) to a block position. Prima::TextView is centered around the text functionality, and although any custom graphic of arbitrary complexity can be embedded in a text block, the internal coordinate system is used ( \s-1TEXT_OFFSET\s0, \s-1BLOCK\s0 ), where \s-1TEXT_OFFSET\s0 is a text offset from the beginning of a block and \s-1BLOCK\s0 is an index of a block. .PP The functionality does not imply any text layout \- this is up to the class descendants, they must provide they own layout policy. The only policy Prima::TextView requires is that blocks' \s-1BLK_TEXT_OFFSET\s0 field must be strictly increasing, and the block text chunks must not overlap. The text gaps are allowed though. .PP A text block basic drawing function includes change of color, backColor and font, and the painting of text strings. Other types of graphics can be achieved by supplying custom code. .SS "Block header" .IX Subsection "Block header" A block's fixed header consists of \f(CW\*(C`tb::BLK_START \- 1\*(C'\fR integer scalars, each of those is accessible via the corresponding \f(CW\*(C`tb::BLK_XXX\*(C'\fR constant. The constants are separated into two logical groups: .PP .Vb 8 \& BLK_FLAGS \& BLK_WIDTH \& BLK_HEIGHT \& BLK_X \& BLK_Y \& BLK_APERTURE_X \& BLK_APERTURE_Y \& BLK_TEXT_OFFSET .Ve .PP and .PP .Vb 5 \& BLK_FONT_ID \& BLK_FONT_SIZE \& BLK_FONT_STYLE \& BLK_COLOR \& BLK_BACKCOLOR .Ve .PP The second group is enclosed in \f(CW\*(C`tb::BLK_DATA_START\*(C'\fR \- \f(CW\*(C`tb::BLK_DATA_END\*(C'\fR range, like the whole header is contained in 0 \- \f(CW\*(C`tb::BLK_START \- 1\*(C'\fR range. This is done for the backward compatibility, if the future development changes the length of the header. .PP The first group fields define the text block dimension, aperture position and text offset ( remember, the text is stored as one big chunk ). The second defines the initial color and font settings. Prima::TextView needs all fields of every block to be initialized before displaying. block_wrap method can be used for automated assigning of these fields. .SS "Block parameters" .IX Subsection "Block parameters" The scalars, beginning from \f(CW\*(C`tb::BLK_START\*(C'\fR, represent the commands to the renderer. These commands have their own parameters, that follow the command. The length of a command is located in \f(CW@oplen\fR array, and must not be changed. The basic command set includes \f(CW\*(C`OP_TEXT\*(C'\fR, \f(CW\*(C`OP_COLOR\*(C'\fR, \f(CW\*(C`OP_FONT\*(C'\fR, \f(CW\*(C`OP_TRANSPOSE\*(C'\fR, and \f(CW\*(C`OP_CODE\*(C'\fR. The additional codes are \f(CW\*(C`OP_WRAP\*(C'\fR and \f(CW\*(C`OP_MARK\*(C'\fR, not used in drawing but are special commands to block_wrap. .IP "\s-1OP_TEXT\s0 \- \s-1TEXT_OFFSET\s0, \s-1TEXT_LENGTH\s0, \s-1TEXT_WIDTH\s0" 4 .IX Item "OP_TEXT - TEXT_OFFSET, TEXT_LENGTH, TEXT_WIDTH" \&\f(CW\*(C`OP_TEXT\*(C'\fR commands to draw a string, from offset \f(CW\*(C`tb::BLK_TEXT_OFFSET + TEXT_OFFSET\*(C'\fR, with a length \s-1TEXT_LENGTH\s0. The third parameter \s-1TEXT_WIDTH\s0 contains the width of the text in pixels. Such the two-part offset scheme is made for simplification or an imaginary code, that would alter ( insert to, or delete part of ) the big text chunk; the updating procedure would not need to traverse all commands, but just the block headers. .Sp Relative to: \f(CW\*(C`tb::BLK_TEXT_OFFSET\*(C'\fR. .IP "\s-1OP_COLOR\s0 \- \s-1COLOR\s0" 4 .IX Item "OP_COLOR - COLOR" \&\f(CW\*(C`OP_COLOR\*(C'\fR sets foreground or background color. To set the background, \&\s-1COLOR\s0 must be or-ed with \f(CW\*(C`tb::BACKCOLOR_FLAG\*(C'\fR value. In addition to the two toolkit supported color values ( \s-1RRGGBB\s0 and system color index ), \&\s-1COLOR\s0 can also be or-ed with \f(CW\*(C`tb::COLOR_INDEX\*(C'\fR flags, in such case it is an index in \f(CW\*(C`::colormap\*(C'\fR property array. .Sp Relative to: \f(CW\*(C`tb::BLK_COLOR\*(C'\fR, \f(CW\*(C`tb::BLK_BACKCOLOR\*(C'\fR. .IP "\s-1OP_FONT\s0 \- \s-1KEY\s0, \s-1VALUE\s0" 4 .IX Item "OP_FONT - KEY, VALUE" As the font is a complex property, that itself includes font name, size, direction, etc keys, \f(CW\*(C`OP_FONT\*(C'\fR \s-1KEY\s0 represents one of the three parameters \- \f(CW\*(C`tb::F_ID\*(C'\fR, \f(CW\*(C`tb::F_SIZE\*(C'\fR, \f(CW\*(C`tb::F_STYLE\*(C'\fR. All three have different \s-1VALUE\s0 meaning. .Sp Relative to: \f(CW\*(C`tb::BLK_FONT_ID\*(C'\fR, \f(CW\*(C`tb::BLK_FONT_SIZE\*(C'\fR, \f(CW\*(C`tb::BLK_FONT_STYLE\*(C'\fR. .RS 4 .IP "F_STYLE" 4 .IX Item "F_STYLE" Contains a combination of \f(CW\*(C`fs::XXX\*(C'\fR constants, such as \f(CW\*(C`fs::Bold\*(C'\fR, \f(CW\*(C`fs::Italic\*(C'\fR etc. .Sp Default value: 0 .IP "F_SIZE" 4 .IX Item "F_SIZE" Contains the relative font size. The size is relative to the current widget's font size. As such, 0 is a default value, and \-2 is the widget's default font decreased by 2 points. Prima::TextView provides no range checking ( but the toolkit does ), so while it is o.k. to set the negative \f(CW\*(C`F_SIZE\*(C'\fR values larger than the default font size, one must be vary when relying on the combined font size value . .Sp If \f(CW\*(C`F_SIZE\*(C'\fR value is added to a \f(CW\*(C`F_HEIGHT\*(C'\fR constant, then it is treated as a font height in pixels rather than font size in points. The macros for these opcodes are named respectively \&\f(CW\*(C`tb::fontSize\*(C'\fR and \f(CW\*(C`tb::fontHeight\*(C'\fR, while the opcode is the same. .IP "F_ID" 4 .IX Item "F_ID" All other font properties are collected under an '\s-1ID\s0'. \s-1ID\s0 is a index in the \f(CW\*(C`::fontPalette\*(C'\fR property array, which contains font hashes with the other font keys initialized \- name, encoding, and pitch. These three are minimal required set, and the other font keys can be also selected. .RE .RS 4 .RE .IP "\s-1OP_TRANSPOSE\s0 X, Y, \s-1FLAGS\s0" 4 .IX Item "OP_TRANSPOSE X, Y, FLAGS" Contains a mark for an empty space. The space is extended to the relative coordinates (X,Y), so the block extension algorithms take this opcode in the account. If \s-1FLAGS\s0 does not contain \&\f(CW\*(C`tb::X_EXTEND\*(C'\fR, then in addition to the block expansion, current coordinate is also moved to (X,Y). In this regard, \f(CW\*(C`(OP_TRANSPOSE,0,0,0)\*(C'\fR and \f(CW\*(C`(OP_TRANSPOSE,0,0,X_EXTEND)\*(C'\fR are identical and are empty operators. .Sp There are formatting-only flags,in effect with block_wrap function. \&\f(CW\*(C`X_DIMENSION_FONT_HEIGHT\*(C'\fR indicates that (X,Y) values must be multiplied to the current font height. Another flag \f(CW\*(C`X_DIMENSION_POINT\*(C'\fR does the same but multiplies by current value of resolution property divided by 72 ( basically, treats X and Y not as pixel but point values). .Sp \&\f(CW\*(C`OP_TRANSPOSE\*(C'\fR can be used for customized graphics, in conjunction with \f(CW\*(C`OP_CODE\*(C'\fR to assign a space, so the rendering algorithms do not need to be re-written every time the new graphic is invented. As an example, see how Prima::PodView deals with the images. .IP "\s-1OP_CODE\s0 \- \s-1SUB\s0, \s-1PARAMETER\s0" 4 .IX Item "OP_CODE - SUB, PARAMETER" Contains a custom code pointer \s-1SUB\s0 with a parameter \s-1PARAMETER\s0, passed when a block is about to be drawn. \s-1SUB\s0 is called with the following format: .Sp .Vb 1 \& ( $widget, $canvas, $text_block, $font_and_color_state, $x, $y, $parameter); .Ve .Sp \&\f(CW$font_and_color_state\fR ( or \f(CW$state\fR, through the code ) contains the state of font and color commands in effect, and is changed as the rendering algorithm advances through a block. The format of the state is the same as of text block, so one may notice that for readability F_ID, F_SIZE, F_STYLE constants are paired to \s-1BLK_FONT_ID\s0, \s-1BLK_FONT_SIZE\s0 and \s-1BLK_FONT_STYLE\s0. .Sp The \s-1SUB\s0 code is executed only when the block is about to draw. .IP "\s-1OP_WRAP\s0 \s-1ON_OFF\s0" 4 .IX Item "OP_WRAP ON_OFF" \&\f(CW\*(C`OP_WRAP\*(C'\fR is only in effect in block_wrap method. \s-1ON_OFF\s0 is a boolean flag, selecting if the wrapping is turned on or off. block_wrap does not support stacking for the wrap commands, so the \f(CW\*(C`(OP_WRAP,1,OP_WRAP,1,OP_WRAP,0)\*(C'\fR has same effect as \f(CW\*(C`(OP_WRAP,0)\*(C'\fR. If \s-1ON_OFF\s0 is 1, wrapping is disabled \- all following commands treated an non-wrapable until \f(CW\*(C`(OP_WRAP,0)\*(C'\fR is met. .IP "\s-1OP_MARK\s0 \s-1PARAMETER\s0, X, Y" 4 .IX Item "OP_MARK PARAMETER, X, Y" \&\f(CW\*(C`OP_MARK\*(C'\fR is only in effect in block_wrap method and is a user command. block_wrap only sets (!) X and Y to the current coordinates when the command is met. Thus, \f(CW\*(C`OP_MARK\*(C'\fR can be used for arbitrary reasons, easy marking the geometrical positions that undergo the block wrapping. .PP As can be noticed, these opcodes are far not enough for the full-weight rich text viewer. However, the new opcodes can be created using \f(CW\*(C`tb::opcode\*(C'\fR, that accepts the opcode length and returns the new opcode value. .SS "Rendering methods" .IX Subsection "Rendering methods" .IP "block_wrap" 4 .IX Item "block_wrap" \&\f(CW\*(C`block_wrap\*(C'\fR is the function, that is used to wrap a block into a given width. It returns one or more text blocks with fully assigned headers. The returned blocks are located one below another, providing an illusion that the text itself is wrapped. It does not only traverses the opcodes and sees if the command fit or not in the given width; it also splits the text strings if these do not fit. .Sp By default the wrapping can occur either on a command boundary or by the spaces or tab characters in the text strings. The unsolicited wrapping can be prevented by using \f(CW\*(C`OP_WRAP\*(C'\fR command brackets. The commands inside these brackets are not wrapped; \f(CW\*(C`OP_WRAP\*(C'\fR commands are removed from the output blocks. .Sp In general, \f(CW\*(C`block_wrap\*(C'\fR copies all commands and their parameters as is, ( as it is supposed to do ), but some commands are treated especially: .Sp \&\- \f(CW\*(C`OP_TEXT\*(C'\fR's third parameter, \f(CW\*(C`TEXT_WIDTH\*(C'\fR, is disregarded, and is recalculated for every \&\f(CW\*(C`OP_TEXT\*(C'\fR met. .Sp \&\- If \f(CW\*(C`OP_TRANSPOSE\*(C'\fR's third parameter, \f(CW\*(C`X_FLAGS\*(C'\fR contains \f(CW\*(C`X_DIMENSION_FONT_HEIGHT\*(C'\fR flag, the command coordinates X and Y are multiplied to the current font height and the flag is cleared in the output block. .Sp \&\- \f(CW\*(C`OP_MARK\*(C'\fR's second and third parameters assigned to the current (X,Y) coordinates. .Sp \&\- \f(CW\*(C`OP_WRAP\*(C'\fR removed from the output. .IP "block_draw \s-1CANVAS\s0, \s-1BLOCK\s0, X, Y" 4 .IX Item "block_draw CANVAS, BLOCK, X, Y" The \f(CW\*(C`block_draw\*(C'\fR draws \s-1BLOCK\s0 onto \s-1CANVAS\s0 in screen coordinates (X,Y). It can not only be used for drawing inside begin_paint/end_paint brackets; \&\s-1CANVAS\s0 can be an arbitrary \f(CW\*(C`Prima::Drawable\*(C'\fR descendant. .SS "Coordinate system methods" .IX Subsection "Coordinate system methods" Prima::TextView employs two its own coordinate systems: (X,Y)\-document and (\s-1TEXT_OFFSET\s0,BLOCK)\-block. .PP The document coordinate system is isometric and measured in pixels. Its origin is located into the imaginary point of the beginning of the document ( not of the first block! ), in the upper-left point. X increases to the right, Y increases downwards. The block header values \s-1BLK_X\s0 and \s-1BLK_Y\s0 are in document coordinates, and the widget's pane extents ( regulated by \f(CW\*(C`::paneSize\*(C'\fR, \f(CW\*(C`::paneWidth\*(C'\fR and \&\f(CW\*(C`::paneHeight\*(C'\fR properties ) are also in document coordinates. .PP The block coordinate system in an-isometric \- its second axis, \s-1BLOCK\s0, is an index of a text block in the widget's blocks storage, \f(CW\*(C`$self\->{blocks}\*(C'\fR, and its first axis, \s-1TEXT_OFFSET\s0 is a text offset from the beginning of the block. .PP Below described different coordinate system converters .IP "screen2point X, Y" 4 .IX Item "screen2point X, Y" Accepts (X,Y) in the screen coordinates ( O is a lower left widget corner ), returns (X,Y) in document coordinates ( O is upper left corner of a document ). .IP "xy2info X, Y" 4 .IX Item "xy2info X, Y" Accepts (X,Y) is document coordinates, returns (\s-1TEXT_OFFSET\s0,BLOCK) coordinates, where \s-1TEXT_OFFSET\s0 is text offset from the beginning of a block ( not related to the big text chunk ) , and \s-1BLOCK\s0 is an index of a block. .IP "info2xy \s-1TEXT_OFFSET\s0, \s-1BLOCK\s0" 4 .IX Item "info2xy TEXT_OFFSET, BLOCK" Accepts (\s-1TEXT_OFFSET\s0,BLOCK) coordinates, and returns (X,Y) in document coordinates of a block. .IP "text2xoffset \s-1TEXT_OFFSET\s0, \s-1BLOCK\s0" 4 .IX Item "text2xoffset TEXT_OFFSET, BLOCK" Returns X coordinate where \s-1TEXT_OFFSET\s0 begins in a \s-1BLOCK\s0 index. .IP "info2text_offset" 4 .IX Item "info2text_offset" Accepts (\s-1TEXT_OFFSET\s0,BLOCK) coordinates and returns the text offset with regard to the big text chunk. .IP "text_offset2info \s-1TEXT_OFFSET\s0" 4 .IX Item "text_offset2info TEXT_OFFSET" Accepts big text offset and returns (\s-1TEXT_OFFSET\s0,BLOCK) coordinates .IP "text_offset2block \s-1TEXT_OFFSET\s0" 4 .IX Item "text_offset2block TEXT_OFFSET" Accepts big text offset and returns \s-1BLOCK\s0 coordinate. .SS "Text selection" .IX Subsection "Text selection" The text selection is performed automatically when the user selects the region with a mouse. The selection is stored in (\s-1TEXT_OFFSET\s0,BLOCK) coordinate pair, and is accessible via the \f(CW\*(C`::selection\*(C'\fR property. If its value is assigned to (\-1,\-1,\-1,\-1) this indicates that there is no selection. For convenience the \f(CW\*(C`has_selection\*(C'\fR method is introduced. .PP Also, \f(CW\*(C`get_selected_text\*(C'\fR returns the text within the selection (or undef with no selection ), and \f(CW\*(C`copy\*(C'\fR copies automatically the selected text into the clipboard. The latter action is bound to \&\f(CW\*(C`Ctrl+Insert\*(C'\fR key combination. .SS "Event rectangles" .IX Subsection "Event rectangles" Partly as an option for future development, partly as a hack a concept of 'event rectangles' was introduced. Currently, \f(CW\*(C`{contents}\*(C'\fR private variable points to an array of objects, equipped with \&\f(CW\*(C`on_mousedown\*(C'\fR, \f(CW\*(C`on_mousemove\*(C'\fR, and \f(CW\*(C`on_mouseup\*(C'\fR methods. These are called within the widget's mouse events, so the overloaded classes can define the interactive content without overloading the actual mouse events ( which is although easy but is dependent on Prima::TextView own mouse reactions ). .PP As an example Prima::PodView uses the event rectangles to catch the mouse events over the document links. Theoretically, every 'content' is to be bound with a separate logical layer; when the concept was designed, a html-browser was in mind, so such layers can be thought as ( in the html world ) links, image maps, layers, external widgets. .PP Currently, \f(CW\*(C`Prima::TextView::EventRectangles\*(C'\fR class is provided for such usage. Its property \f(CW\*(C`::rectangles\*(C'\fR contains an array of rectangles, and the \f(CW\*(C`contains\*(C'\fR method returns an integer value, whether the passed coordinates are inside one of its rectangles or not; in the first case it is the rectangle index.