/usr/include/cwidget/fragment.h is in libcwidget-dev 0.5.16-3.1ubuntu1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 | // fragment.h -*-c++-*-
//
// Copyright (C) 2004-2005, 2007 Daniel Burrows
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of
// the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; see the file COPYING. If not, write to
// the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
// Boston, MA 02111-1307, USA.
//
// Fragments are pieces of text that live in a text_layout widget.
// See widgets/text_layout.h for details.
#ifndef FRAGMENT_H
#define FRAGMENT_H
#include "fragment_contents.h"
#include <cwidget/style.h>
#include <string>
#include <vector>
namespace cwidget
{
/** A fragment represents a logical unit of text.
*/
class fragment
{
public:
/** Return all the lines of this fragment, given the "shape" of the
* fragment. Note that some fragments ignore the given widths, so
* the caller is expected to either put everything in a formatting
* box (one that forces its contents to stay "in bounds") or
* manually clip the return value.
*
* \param firstw the width to which the first line of the fragment
* should be formatted.
*
* \param w the width to which subsequent lines of the fragment
* should be formatted.
*
* \param s the enclosing style of this fragment. The fragment's
* size is guaranteed to be independent of s.
*
* \return the lines of this fragment; the caller is responsible
* for deleting it.
*/
virtual fragment_contents layout(size_t firstw,
size_t w,
const style &st)=0;
/** \param first_indent the indentation of the first line, relative
* to a baseline (which may be outside this fragment).
*
* \param rest_indent the indentation of any other lines.
*
* \return the maximum length of any line in this fragment. Any
* call to layout() with a width greater than this maximum length
* will produce the same result.
*/
virtual size_t max_width(size_t first_indent,
size_t rest_indent) const=0;
/** \param first_indent the indentation of the first line.
*
* \param rest_indent the indentation of any other lines.
*
* \return the length of any "trailing" line in the fragment,
* including indentation.
*/
virtual size_t trailing_width(size_t first_indent,
size_t rest_indent) const=0;
/** \return \b true if this fragment ends in a newline. */
virtual bool final_newline() const=0;
/** Nothing to do in the base class */
virtual ~fragment();
};
// Factory methods to avoid cluttering the .h file:
/** Create a fragment from a string of text. The text will simply be
* formatted as is, with line breaks at newlines and tabs replaced by
* eight spaces.
*
* \param s the text to use
*
* \return the new fragment
*/
fragment *text_fragment(const std::wstring &s);
/** Create a fragment from a string of text. The text will simply be
* formatted as a single line without clipping.
*
* \param s the text to use
* \param style the base style for the new fragment; an implicit
* style_fragment for this style is wrapped around the new text_fragment.
*
* \return the new fragment
*/
fragment *text_fragment(const std::wstring &s,
const style &st);
/** Create a fragment from a string of multibyte-encoded text.
*
* \param s the text to use
* \param encoding the text's encoding; if this is \b null or
* unspecified, LC_CTYPE will be used.
*
* \return the new fragment
*/
fragment *text_fragment(const std::string &s,
const char *encoding=NULL);
/** Create a fragment from a string of multibyte-encoded text,
* wrapping an implicit style_fragment around it.
*/
fragment *text_fragment(const std::string &s,
const style &st,
const char *encoding=NULL);
/** Create a fragment from a string of text. The text will simply be
* formatted as a single line without clipping.
*
* \param s the text to use
* \param attr attributes to assign to it
*
* \return the new fragment
*/
inline fragment *text_fragment(const char *s,
const style &st=style())
{
return text_fragment(std::string(s), st);
}
/** Create a fragment which simply produces a newline wherever it occurs. */
fragment *newline_fragment();
/** Create a fragment which alters the style of its contents.
*
* \param f the child of this fragment
* \param attr the text attribute which should be assigned to f
*
* \return the new fragment
*/
fragment *style_fragment(fragment *f,
const style &st);
/** Create a fragment from a sequence of other fragments.
*
* The fragment will simply "shove" the two sequences together,
* respecting the value of final_nl on each.
*
* \todo can this be made more efficient? It should be possible to
* just "plug" the sequences together if they're lists -- but that only
* works if they aren't cached elsewhere.
*
* \param fragments the fragments in the sequence
*
* \return the new fragment
*/
fragment *sequence_fragment(const std::vector<fragment *> &fragments);
/** Create a fragment from a sequence of other fragments.
*
* The fragment will simply "shove" the two sequences together,
* respecting the value of final_nl on each.
*
* \param f the first fragment in the sequence; the sequence should
* be terminated with a NULL pointer.
*
* \return the new fragment
*/
fragment *sequence_fragment(fragment *f, ...);
/** Join fragments into a single fragment, placing text between them.
*
* This is useful for creating lists, for instance. The new fragment
* takes ownership of all pointers in fragments.
*
* \param fragments the list of fragments to join
* \param between a string to place between adjacent items in the input list
*/
fragment *join_fragments(const std::vector<fragment *> &fragments,
const std::wstring &between);
/** Create a flowbox.
*
* Each line of the fragment placed inside the flowbox will be
* reflowed (word-wrapped) to the current width, possibly to
* several lines.
*
* The contents of a flowbox always have final_nl=\b true. (ie, a
* flowbox is always followed by a line break)
*
* \param contents the contents of the flowbox
*
* \return the new flowbox
*/
fragment *flowbox(fragment *contents);
/** Create a fillbox.
*
* Each line of the fragment placed inside the fillbox will be
* reflowed (word-wrapped) and expanded to the current width,
* possibly to several lines.
*
* The contents of a fillbox always have final_nl=\b true.
*
* \param contents the contents of the fillbox
*
* \return the new fillbox
*/
fragment *fillbox(fragment *contents);
/** Create a hardwrapbox.
*
* Each line of the fragment inside the box will be hard-wrapped
* to the current width.
*
* The contents of a wrapbox always have final_nl=\b true.
*
* \param contents the contents of the hardwrapbox
*
* \return the new hardwrapbox
*/
fragment *hardwrapbox(fragment *contents);
/** Create a clipbox.
*
* Each line of the fragment placed inside the clipbox will be
* clipped to the current width. The whole layout widget
* implicitly uses one of these, but there may be other uses for
* clipboxes as well.
*
* \param contents the contents of the clipbox
*
* \return the new clipbox
*/
fragment *clipbox(fragment *contents);
/** Create an indentbox.
*
* Each line of the indentbox will be indented by the specified
* amount. (this effectively decreases the width of each line) If
* desired, the first line can be indented a different amount
* (typically less) than the remaining lines, although it is
* formatted to the same width; this supports things like bulletted
* lists.
*
* \param firstindent the number of spaces of indentation to use for the first line
* \param restindent the number of spaces of indentation to use for later lines
* \param contents the contents of the indentbox
* \return the new indentbox
*/
fragment *indentbox(size_t firstindent, size_t restindent, fragment *contents);
/** Indent a paragraph, placing the given text on the first line.
*
* This just expands to an invocation of indentbox, with the
* indentation constants set appropriately. The result will consist
* of "header" prepended to the first line of "contents", with
* successive lines of "contents" indented to line up with the first
* line of "contents".
*/
fragment *dropbox(fragment *header, fragment *contents);
/** Stores information on a single column of fragments. */
struct fragment_column_entry
{
/** If \b true, this column is allocated space proportionally;
* otherwise, its width is exactly what is specified.
*/
bool proportional;
/** If proportional is \b false and the fragment is not NULL, then
* setting this to \b true means that the width below will be
* expanded to max_width if necessary. If the resulting fragment
* exceeds the screen width, it will be shrunk as necessary.
*/
bool expandable;
/** If proportional is \b true, this is a number giving the relative
* size of this column compared to other proportional columns;
* otherwise, this is the width of the column in character cells.
*/
size_t width;
enum align {top, center, bottom};
/** The vertical alignment of the column. If top, the top of this
* column is placed at the top of the fragment. If center, the
* center of this column is aligned with the center of the
* fragment. And if bottom, the bottom of this column is aligned
* with the bottom of the fragment.
*/
align vert_align;
/** The vertical components of this column.
*
* Each vertical entry in the column will begin on the same line as
* the corresponding vertical entries in the other columns. If not
* all columns have the same number of vertical entries, the
* shorter columns are padded with blank lines to be the same
* length as the longer columns.
*
* NULL entries produce blank lines.
*/
std::vector<fragment *>lines;
/** \brief Create a fragment column that has a single line. */
fragment_column_entry(bool _proportional,
bool _expandable,
size_t _width, align _vert_align,
fragment *f)
:proportional(_proportional),
expandable(_expandable),
width(_width),
vert_align(_vert_align)
{
lines.push_back(f);
}
fragment_column_entry(bool _proportional,
bool _expandable,
size_t _width, align _vert_align,
const std::vector<fragment *> &_lines)
:proportional(_proportional),
expandable(_expandable),
width(_width),
vert_align(_vert_align),
lines(_lines)
{
}
fragment_column_entry()
:proportional(false), width(0), vert_align(top)
{
}
};
/** A fragment that formats its contents into columns. If the
* fixed-width columns overflow the available space, they will be
* clipped hard.
*
* This fragment may NOT be placed inside an indent box or any other
* box that alters the shape of its contents. Doing so will cause
* the program to abort.
*
* \param columns a list of column entry information ordered from
* left to right.
*/
fragment *fragment_columns(const std::vector<fragment_column_entry> &columns);
/** A printf-alike for fragments.
*
* Formatting codes:
*
* - %F: substitutes a fragment into the sequence being built
* - %s: substitutes a const char * into the sequence being built
* with transcoding according to LC_CTYPE
* - %n: substitutes a newline fragment into the sequence being built
* - %%: inserts a literal %
* - %B/%b: toggle the bold character attribute
* - %R/%r: toggle the reverse video character attribute
* - %D/%d: toggle the dim character attribute
* - %S: Apply the style corresponding to a
* string (looked up via get_style) to the attributes.
* - %N: Reset the text style to the empty ("null") style.
*
* For instance,
*
* fragf("%S%BWARNING%b: something bad happened in routine %s,"
* "expect a segfault.", "Error", some_routine);
*
* Note: if you use a parameter index multiple times, you are virtually
* GUARANTEED to segfault!
*
* \param format the format string
* \return the formatted fragment, or NULL if there is an error in the format.
*/
fragment *fragf(const char *format, ...);
}
#endif
|