Dillo
Main Page
Related Pages
Namespaces
Classes
Files
File List
File Members
dw
textblock.hh
Go to the documentation of this file.
1
#ifndef __DW_TEXTBLOCK_HH__
2
#define __DW_TEXTBLOCK_HH__
3
4
#include <limits.h>
5
6
#include "
core.hh
"
7
#include "../lout/misc.hh"
8
9
// These were used when improved line breaking and hyphenation were
10
// implemented. Should be cleaned up; perhaps reactivate RTFL again.
11
#define PRINTF(fmt, ...)
12
#define PUTCHAR(ch)
13
14
namespace
dw {
15
144
class
Textblock
:
public
core::Widget
145
{
146
private
:
155
class
BadnessAndPenalty
156
{
157
private
:
158
enum
{
NOT_STRETCHABLE
,
QUITE_LOOSE
,
BADNESS_VALUE
,
TOO_TIGHT
}
159
badnessState
;
160
enum
{
FORCE_BREAK
,
PROHIBIT_BREAK
,
PENALTY_VALUE
}
penaltyState
;
161
int
ratio
;
// ratio is only defined when badness is defined
162
int
badness
,
penalty
;
163
164
// for debugging:
165
int
totalWidth
,
idealWidth
,
totalStretchability
,
totalShrinkability
;
166
167
// "Infinity levels" are used to represent very large numbers,
168
// including "quasi-infinite" numbers. A couple of infinity
169
// level and number can be mathematically represented as
170
//
171
// number * N ^ (infinity level)
172
//
173
// where N is a number which is large enough. Practically,
174
// infinity levels are used to circumvent limited ranges for
175
// integer numbers.
176
177
// Here, all infinity levels have got special meanings.
178
enum
{
179
INF_VALUE
= 0,
/* simple values */
180
INF_LARGE
,
/* large values, like QUITE_LOOSE */
181
INF_NOT_STRETCHABLE
,
/* reserved for NOT_STRECTHABLE */
182
INF_TOO_TIGHT
,
/* used for lines, which are too tight */
183
INF_PENALTIES
,
/* used for penalties */
184
INF_MAX
=
INF_PENALTIES
185
186
// That INF_PENALTIES is the last value means that an
187
// infinite penalty (breaking is prohibited) makes a break
188
// not possible at all, so that pre-formatted text
189
// etc. works.
190
};
191
192
int
badnessValue
(
int
infLevel);
193
int
penaltyValue
(
int
infLevel);
194
195
public
:
196
void
calcBadness
(
int
totalWidth
,
int
idealWidth
,
197
int
totalStretchability
,
int
totalShrinkability
);
198
void
setPenalty
(
int
penalty
);
199
void
setPenaltyProhibitBreak
();
200
void
setPenaltyForceBreak
();
201
202
bool
lineLoose
();
203
bool
lineTight
();
204
bool
lineTooTight
();
205
bool
lineMustBeBroken
();
206
bool
lineCanBeBroken
();
207
int
compareTo
(
BadnessAndPenalty
*other);
208
209
void
print
();
210
};
211
212
protected
:
213
enum
{
219
HYPHEN_BREAK
= 100
220
};
221
222
struct
Line
223
{
224
int
firstWord
;
/* first word's index in word vector */
225
int
lastWord
;
/* last word's index in word vector */
226
227
/* "top" is always relative to the top of the first line, i.e.
228
* page->lines[0].top is always 0. */
229
int
top
,
boxAscent
,
boxDescent
,
contentAscent
,
contentDescent
,
230
breakSpace
,
leftOffset
;
231
232
/* This is similar to descent, but includes the bottom margins of the
233
* widgets within this line. */
234
int
marginDescent
;
235
236
/* The following members contain accumulated values, from the
237
* top down to this line. Please notice a change: until
238
* recently, the values were accumulated up to the last line,
239
* not this line.
240
*
241
* Also, keep in mind that at the end of a line, the space of
242
* the last word is ignored, but instead, the hyphen width must
243
* be considered.*/
244
245
int
maxLineWidth
;
/* Maximum of all line widths, including this
246
* line. Does not include the last space, but
247
* the last hyphen width. */
248
int
maxParMin
;
/* Maximum of all paragraph minima, including
249
* this line. */
250
int
maxParMax
;
/* Maximum of all paragraph maxima. This line
251
* is only included, if it is the last line of
252
* the paragraph (last word is a forced
253
* break); otherwise, it is the value of the
254
* last paragraph. For this reason, consider
255
* also parMax. */
256
int
parMax
;
/* The maximal total width down from the last
257
* paragraph start, to the *end* of this line.
258
* The space at the end of this line is
259
* included, but not the hyphen width (as
260
* opposed to the other values). So, in some
261
* cases, the space has to be subtracted and
262
* the hyphen width to be added, to compare it
263
* to maxParMax. (Search the code for
264
* occurances.) */
265
};
266
267
struct
Word
268
{
269
/* TODO: perhaps add a xLeft? */
270
core::Requisition
size
;
271
/* Space after the word, only if it's not a break: */
272
short
origSpace
;
/* from font, set by addSpace */
273
short
stretchability
,
shrinkability
;
274
short
effSpace
;
/* effective space, set by wordWrap,
275
* used for drawing etc. */
276
short
hyphenWidth
;
/* Additional width, when a word is part
277
* (except the last part) of a hyphenationed
278
* word. Has to be added to the width, when
279
* this is the last word of the line, and
280
* "hyphenWidth > 0" is also used to decide
281
* whether to draw a hyphen. */
282
core::Content
content
;
283
bool
canBeHyphenated
;
284
285
// accumulated values, relative to the beginning of the line
286
int
totalWidth
;
/* The sum of all word widths; plus all
287
spaces, excluding the one of this
288
word; plus the hyphen width of this
289
word (but of course, no hyphen
290
widths of previous words. In other
291
words: the value compared to the
292
ideal width of the line, if the line
293
would be broken after this word. */
294
int
totalStretchability
;
// includes all *before* current word
295
int
totalShrinkability
;
// includes all *before* current word
296
BadnessAndPenalty
badnessAndPenalty
;
/* when line is broken after this
297
* word */
298
299
core::style::Style
*
style
;
300
core::style::Style
*
spaceStyle
;
/* initially the same as of the word,
301
later set by a_Dw_page_add_space */
302
};
303
304
void
printWord
(
Word
*word);
305
306
struct
Anchor
307
{
308
char
*
name
;
309
int
wordIndex
;
310
};
311
312
class
TextblockIterator
:
public
core::Iterator
313
{
314
private
:
315
int
index
;
316
317
public
:
318
TextblockIterator
(
Textblock
*textblock,
core::Content::Type
mask
,
319
bool
atEnd);
320
TextblockIterator
(
Textblock
*textblock,
core::Content::Type
mask
,
321
int
index
);
322
323
lout::object::Object
*
clone
();
324
int
compareTo
(
lout::misc::Comparable
*other);
325
326
bool
next
();
327
bool
prev
();
328
void
highlight
(
int
start,
int
end,
core::HighlightLayer
layer);
329
void
unhighlight
(
int
direction,
core::HighlightLayer
layer);
330
void
getAllocation
(
int
start,
int
end,
core::Allocation
*
allocation
);
331
};
332
333
friend
class
TextblockIterator
;
334
335
/* These fields provide some ad-hoc-functionality, used by sub-classes. */
336
bool
hasListitemValue
;
/* If true, the first word of the page is treated
337
specially (search in source). */
338
int
innerPadding
;
/* This is an additional padding on the left side
339
(used by ListItem). */
340
int
line1Offset
;
/* This is an additional offset of the first line.
341
May be negative (shift to left) or positive
342
(shift to right). */
343
int
line1OffsetEff
;
/* The "effective" value of line1_offset, may
344
differ from line1_offset when
345
ignoreLine1OffsetSometimes is set to true. */
346
347
/* The following is really hackish: It is used for DwTableCell (see
348
* comment in dw_table_cell.c), to avoid too wide table columns. If
349
* set to true, it has following effects:
350
*
351
* (i) line1_offset is ignored in calculating the minimal width
352
* (which is used by DwTable!), and
353
* (ii) line1_offset is ignored (line1_offset_eff is set to 0),
354
* when line1_offset plus the width of the first word is
355
* greater than the the available witdh.
356
*
357
* \todo Eliminate all these ad-hoc features by a new, simpler and
358
* more elegant design. ;-)
359
*/
360
bool
ignoreLine1OffsetSometimes
;
361
362
bool
mustQueueResize
;
363
364
bool
limitTextWidth
;
/* from preferences */
365
366
int
redrawY
;
367
int
lastWordDrawn
;
368
369
/* These values are set by set_... */
370
int
availWidth
,
availAscent
,
availDescent
;
371
372
int
wrapRef
;
/* [0 based] */
373
374
lout::misc::SimpleVector <Line>
*
lines
;
375
int
nonTemporaryLines
;
376
lout::misc::NotSoSimpleVector <Word>
*
words
;
377
lout::misc::SimpleVector <Anchor>
*
anchors
;
378
379
struct
{
int
index
,
nChar
;}
380
hlStart
[
core::HIGHLIGHT_NUM_LAYERS
],
hlEnd
[
core::HIGHLIGHT_NUM_LAYERS
];
381
382
int
hoverLink
;
/* The link under the mouse pointer */
383
384
385
void
queueDrawRange
(
int
index1,
int
index2);
386
void
getWordExtremes
(
Word
*word,
core::Extremes
*
extremes
);
387
void
markChange
(
int
ref);
388
void
justifyLine
(
Line
*line,
int
diff);
389
Line
*
addLine
(
int
firstWord,
int
lastWord,
bool
temporary);
390
void
calcWidgetSize
(
core::Widget
*widget,
core::Requisition
*size);
391
void
rewrap
();
392
void
showMissingLines
();
393
void
removeTemporaryLines
();
394
395
void
decorateText
(
core::View
*view,
core::style::Style
*
style
,
396
core::style::Color::Shading
shading,
397
int
x,
int
yBase,
int
width);
398
void
drawText
(
core::View
*view,
core::style::Style
*
style
,
399
core::style::Color::Shading
shading,
int
x,
int
y,
400
const
char
*text,
int
start,
int
len);
401
void
drawWord
(
Line
*line,
int
wordIndex1,
int
wordIndex2,
core::View
*view,
402
core::Rectangle
*area,
int
xWidget,
int
yWidgetBase);
403
void
drawWord0
(
int
wordIndex1,
int
wordIndex2,
404
const
char
*text,
int
totalWidth,
405
core::style::Style
*
style
,
core::View
*view,
406
core::Rectangle
*area,
int
xWidget,
int
yWidgetBase);
407
void
drawSpace
(
int
wordIndex,
core::View
*view,
core::Rectangle
*area,
408
int
xWidget,
int
yWidgetBase);
409
void
drawLine
(
Line
*line,
core::View
*view,
core::Rectangle
*area);
410
int
findLineIndex
(
int
y);
411
int
findLineOfWord
(
int
wordIndex);
412
Word
*
findWord
(
int
x,
int
y,
bool
*inSpace);
413
414
Word
*
addWord
(
int
width,
int
ascent,
int
descent,
bool
canBeHyphenated,
415
core::style::Style
*
style
);
416
void
fillWord
(
Word
*word,
int
width,
int
ascent,
int
descent,
417
bool
canBeHyphenated,
core::style::Style
*
style
);
418
void
fillSpace
(
Word
*word,
core::style::Style
*
style
);
419
void
setBreakOption
(
Word
*word,
core::style::Style
*
style
);
420
int
textWidth
(
const
char
*text,
int
start,
int
len,
421
core::style::Style
*
style
);
422
void
calcTextSize
(
const
char
*text,
size_t
len,
core::style::Style
*
style
,
423
core::Requisition
*size);
424
432
inline
int
lineXOffsetContents
(
Line
*line)
433
{
434
return
innerPadding
+ line->
leftOffset
+
435
(line ==
lines
->
getFirstRef
() ?
line1OffsetEff
: 0);
436
}
437
442
inline
int
lineXOffsetWidget
(
Line
*line)
443
{
444
return
lineXOffsetContents
(line) +
getStyle
()->
boxOffsetX
();
445
}
446
447
inline
int
lineYOffsetWidgetAllocation
(
Line
*line,
448
core::Allocation
*
allocation
)
449
{
450
return
line->
top
+ (allocation->
ascent
-
lines
->
getRef
(0)->
boxAscent
);
451
}
452
453
inline
int
lineYOffsetWidget
(
Line
*line)
454
{
455
return
lineYOffsetWidgetAllocation
(line, &
allocation
);
456
}
457
461
inline
int
lineYOffsetCanvasAllocation
(
Line
*line,
462
core::Allocation
*
allocation
)
463
{
464
return
allocation->
y
+
lineYOffsetWidgetAllocation
(line, allocation);
465
}
466
470
inline
int
lineYOffsetCanvas
(
Line
*line)
471
{
472
return
lineYOffsetCanvasAllocation
(line, &
allocation
);
473
}
474
475
inline
int
lineYOffsetWidgetI
(
int
lineIndex)
476
{
477
return
lineYOffsetWidget
(
lines
->
getRef
(lineIndex));
478
}
479
480
inline
int
lineYOffsetCanvasI
(
int
lineIndex)
481
{
482
return
lineYOffsetCanvas
(
lines
->
getRef
(lineIndex));
483
}
484
485
bool
sendSelectionEvent
(
core::SelectionState::EventType
eventType,
486
core::MousePositionEvent
*event);
487
488
void
accumulateWordExtremes
(
int
firstWord,
int
lastWord,
489
int
*maxOfMinWidth,
int
*sumOfMaxWidth);
490
virtual
void
wordWrap
(
int
wordIndex,
bool
wrapAll);
491
int
hyphenateWord
(
int
wordIndex);
492
void
accumulateWordForLine
(
int
lineIndex,
int
wordIndex);
493
void
accumulateWordData
(
int
wordIndex);
494
int
calcAvailWidth
(
int
lineIndex);
495
void
initLine1Offset
(
int
wordIndex);
496
void
alignLine
(
int
lineIndex);
497
498
void
sizeRequestImpl
(
core::Requisition
*
requisition
);
499
void
getExtremesImpl
(
core::Extremes
*
extremes
);
500
void
sizeAllocateImpl
(
core::Allocation
*
allocation
);
501
void
resizeDrawImpl
();
502
503
void
markSizeChange
(
int
ref);
504
void
markExtremesChange
(
int
ref);
505
void
setWidth
(
int
width);
506
void
setAscent
(
int
ascent);
507
void
setDescent
(
int
descent);
508
void
draw
(
core::View
*view,
core::Rectangle
*area);
509
510
bool
buttonPressImpl
(
core::EventButton
*event);
511
bool
buttonReleaseImpl
(
core::EventButton
*event);
512
bool
motionNotifyImpl
(
core::EventMotion
*event);
513
void
enterNotifyImpl
(
core::EventCrossing
*event);
514
void
leaveNotifyImpl
(
core::EventCrossing
*event);
515
516
void
removeChild
(
Widget
*child);
517
518
void
addText0
(
const
char
*text,
size_t
len,
bool
canBeHyphenated,
519
core::style::Style
*
style
,
core::Requisition
*size);
520
void
calcTextSizes
(
const
char
*text,
size_t
textLen,
521
core::style::Style
*
style
,
522
int
numBreaks,
int
*breakPos,
523
core::Requisition
*wordSize);
524
525
public
:
526
static
int
CLASS_ID
;
527
528
Textblock
(
bool
limitTextWidth
);
529
~Textblock
();
530
531
core::Iterator
*
iterator
(
core::Content::Type
mask,
bool
atEnd);
532
533
void
flush
();
534
535
void
addText
(
const
char
*text,
size_t
len,
core::style::Style
*
style
);
536
inline
void
addText
(
const
char
*text,
core::style::Style
*
style
)
537
{
538
addText
(text, strlen(text), style);
539
}
540
void
addWidget
(
core::Widget
*widget,
core::style::Style
*
style
);
541
bool
addAnchor
(
const
char
*name,
core::style::Style
*
style
);
542
void
addSpace
(
core::style::Style
*
style
);
543
548
inline
void
addBreakOption
(
core::style::Style
*
style
)
549
{
550
int
wordIndex =
words
->
size
() - 1;
551
if
(wordIndex >= 0)
552
setBreakOption
(
words
->
getRef
(wordIndex),
style
);
553
}
554
555
void
addHyphen
();
556
void
addParbreak
(
int
space,
core::style::Style
*
style
);
557
void
addLinebreak
(
core::style::Style
*
style
);
558
559
core::Widget
*
getWidgetAtPoint
(
int
x,
int
y,
int
level);
560
void
handOverBreak
(
core::style::Style
*
style
);
561
void
changeLinkColor
(
int
link,
int
newColor);
562
void
changeWordStyle
(
int
from,
int
to,
core::style::Style
*
style
,
563
bool
includeFirstSpace,
bool
includeLastSpace);
564
};
565
566
}
// namespace dw
567
568
#endif // __DW_TEXTBLOCK_HH__
Generated on Mon Nov 5 2012 02:16:32 for Dillo by
1.8.2