~ubuntu-branches/ubuntu/natty/luatex/natty

« back to all changes in this revision

Viewing changes to source/libs/poppler/poppler-0.12.4/poppler/TextOutputDev.h

  • Committer: Package Import Robot
  • Author(s): Norbert Preining
  • Date: 2010-12-13 23:22:59 UTC
  • mfrom: (0.2.1) (1.5.4) (4.3.12 experimental)
  • Revision ID: package-import@ubuntu.com-20101213232259-nqq2mq5z5x6qldw3
Tags: 0.65.0-1
* new upstream release
* ship two source packages as they are distributed by upstream, only
  renamed to match source package requirements. Fix debian/rules
  to install the manual pdf from the right place

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
//========================================================================
 
2
//
 
3
// TextOutputDev.h
 
4
//
 
5
// Copyright 1997-2003 Glyph & Cog, LLC
 
6
//
 
7
//========================================================================
 
8
 
 
9
//========================================================================
 
10
//
 
11
// Modified under the Poppler project - http://poppler.freedesktop.org
 
12
//
 
13
// Copyright (C) 2005-2007 Kristian Høgsberg <krh@redhat.com>
 
14
// Copyright (C) 2006 Ed Catmur <ed@catmur.co.uk>
 
15
// Copyright (C) 2007-2008 Carlos Garcia Campos <carlosgc@gnome.org>
 
16
// Copyright (C) 2007 Adrian Johnson <ajohnson@redneon.com>
 
17
// Copyright (C) 2008 Albert Astals Cid <aacid@kde.org>
 
18
//
 
19
// To see a description of the changes please see the Changelog file that
 
20
// came with your tarball or type make ChangeLog if you are building from git
 
21
//
 
22
//========================================================================
 
23
 
 
24
#ifndef TEXTOUTPUTDEV_H
 
25
#define TEXTOUTPUTDEV_H
 
26
 
 
27
#ifdef USE_GCC_PRAGMAS
 
28
#pragma interface
 
29
#endif
 
30
 
 
31
#include "poppler-config.h"
 
32
#include <stdio.h>
 
33
#include "goo/gtypes.h"
 
34
#include "GfxFont.h"
 
35
#include "GfxState.h"
 
36
#include "OutputDev.h"
 
37
 
 
38
class GooString;
 
39
class GooList;
 
40
class Gfx;
 
41
class GfxFont;
 
42
class GfxState;
 
43
class UnicodeMap;
 
44
class Link;
 
45
 
 
46
class TextWord;
 
47
class TextPool;
 
48
class TextLine;
 
49
class TextLineFrag;
 
50
class TextBlock;
 
51
class TextFlow;
 
52
class TextWordList;
 
53
class TextPage;
 
54
class TextSelectionVisitor;
 
55
 
 
56
//------------------------------------------------------------------------
 
57
 
 
58
typedef void (*TextOutputFunc)(void *stream, char *text, int len);
 
59
 
 
60
enum SelectionStyle {
 
61
  selectionStyleGlyph,
 
62
  selectionStyleWord,
 
63
  selectionStyleLine
 
64
};
 
65
 
 
66
//------------------------------------------------------------------------
 
67
// TextFontInfo
 
68
//------------------------------------------------------------------------
 
69
 
 
70
class TextFontInfo {
 
71
public:
 
72
 
 
73
  TextFontInfo(GfxState *state);
 
74
  ~TextFontInfo();
 
75
 
 
76
  GBool matches(GfxState *state);
 
77
 
 
78
#if TEXTOUT_WORD_LIST
 
79
  // Get the font name (which may be NULL).
 
80
  GooString *getFontName() { return fontName; }
 
81
 
 
82
  // Get font descriptor flags.
 
83
  GBool isFixedWidth() { return flags & fontFixedWidth; }
 
84
  GBool isSerif() { return flags & fontSerif; }
 
85
  GBool isSymbolic() { return flags & fontSymbolic; }
 
86
  GBool isItalic() { return flags & fontItalic; }
 
87
  GBool isBold() { return flags & fontBold; }
 
88
#endif
 
89
 
 
90
private:
 
91
 
 
92
  GfxFont *gfxFont;
 
93
#if TEXTOUT_WORD_LIST
 
94
  GooString *fontName;
 
95
  int flags;
 
96
#endif
 
97
 
 
98
  friend class TextWord;
 
99
  friend class TextPage;
 
100
  friend class TextSelectionPainter;
 
101
};
 
102
 
 
103
//------------------------------------------------------------------------
 
104
// TextWord
 
105
//------------------------------------------------------------------------
 
106
 
 
107
class TextWord {
 
108
public:
 
109
 
 
110
  // Constructor.
 
111
  TextWord(GfxState *state, int rotA, double x0, double y0,
 
112
           int charPosA, TextFontInfo *fontA, double fontSize);
 
113
 
 
114
  // Destructor.
 
115
  ~TextWord();
 
116
 
 
117
  // Add a character to the word.
 
118
  void addChar(GfxState *state, double x, double y,
 
119
               double dx, double dy, CharCode c, Unicode u);
 
120
 
 
121
  // Merge <word> onto the end of <this>.
 
122
  void merge(TextWord *word);
 
123
 
 
124
  // Compares <this> to <word>, returning -1 (<), 0 (=), or +1 (>),
 
125
  // based on a primary-axis comparison, e.g., x ordering if rot=0.
 
126
  int primaryCmp(TextWord *word);
 
127
 
 
128
  // Return the distance along the primary axis between <this> and
 
129
  // <word>.
 
130
  double primaryDelta(TextWord *word);
 
131
 
 
132
  static int cmpYX(const void *p1, const void *p2);
 
133
 
 
134
  void visitSelection(TextSelectionVisitor *visitor,
 
135
                      PDFRectangle *selection,
 
136
                      SelectionStyle style);
 
137
 
 
138
  // Get the TextFontInfo object associated with this word.
 
139
  TextFontInfo *getFontInfo() { return font; }
 
140
 
 
141
  // Get the next TextWord on the linked list.
 
142
  TextWord *getNext() { return next; }
 
143
 
 
144
#if TEXTOUT_WORD_LIST
 
145
  int getLength() { return len; }
 
146
  const Unicode *getChar(int idx) { return &text[idx]; }
 
147
  GooString *getText();
 
148
  GooString *getFontName() { return font->fontName; }
 
149
  void getColor(double *r, double *g, double *b)
 
150
    { *r = colorR; *g = colorG; *b = colorB; }
 
151
  void getBBox(double *xMinA, double *yMinA, double *xMaxA, double *yMaxA)
 
152
    { *xMinA = xMin; *yMinA = yMin; *xMaxA = xMax; *yMaxA = yMax; }
 
153
  void getCharBBox(int charIdx, double *xMinA, double *yMinA,
 
154
                   double *xMaxA, double *yMaxA);
 
155
  double getFontSize() { return fontSize; }
 
156
  int getRotation() { return rot; }
 
157
  int getCharPos() { return charPos; }
 
158
  int getCharLen() { return charLen; }
 
159
  GBool getSpaceAfter() { return spaceAfter; }
 
160
#endif
 
161
  GBool isUnderlined() { return underlined; }
 
162
  Link *getLink() { return link; }
 
163
  double getEdge(int i) { return edge[i]; }
 
164
  double getBaseline () { return base; }
 
165
  GBool hasSpaceAfter  () { return spaceAfter; }
 
166
  TextWord* nextWord () { return next; };
 
167
private:
 
168
 
 
169
  int rot;                      // rotation, multiple of 90 degrees
 
170
                                //   (0, 1, 2, or 3)
 
171
  double xMin, xMax;            // bounding box x coordinates
 
172
  double yMin, yMax;            // bounding box y coordinates
 
173
  double base;                  // baseline x or y coordinate
 
174
  Unicode *text;                // the text
 
175
  CharCode *charcode;           // glyph indices
 
176
  double *edge;                 // "near" edge x or y coord of each char
 
177
                                //   (plus one extra entry for the last char)
 
178
  int len;                      // length of text and edge arrays
 
179
  int size;                     // size of text and edge arrays
 
180
  int charPos;                  // character position (within content stream)
 
181
  int charLen;                  // number of content stream characters in
 
182
                                //   this word
 
183
  TextFontInfo *font;           // font information
 
184
  double fontSize;              // font size
 
185
  GBool spaceAfter;             // set if there is a space between this
 
186
                                //   word and the next word on the line
 
187
  TextWord *next;               // next word in line
 
188
 
 
189
#if TEXTOUT_WORD_LIST
 
190
  double colorR,                // word color
 
191
         colorG,
 
192
         colorB;
 
193
#endif
 
194
 
 
195
  GBool underlined;
 
196
  Link *link;
 
197
 
 
198
  friend class TextPool;
 
199
  friend class TextLine;
 
200
  friend class TextBlock;
 
201
  friend class TextFlow;
 
202
  friend class TextWordList;
 
203
  friend class TextPage;
 
204
 
 
205
  friend class TextSelectionPainter;
 
206
  friend class TextSelectionDumper;
 
207
};
 
208
 
 
209
//------------------------------------------------------------------------
 
210
// TextPool
 
211
//------------------------------------------------------------------------
 
212
 
 
213
class TextPool {
 
214
public:
 
215
 
 
216
  TextPool();
 
217
  ~TextPool();
 
218
 
 
219
  TextWord *getPool(int baseIdx) { return pool[baseIdx - minBaseIdx]; }
 
220
  void setPool(int baseIdx, TextWord *p) { pool[baseIdx - minBaseIdx] = p; }
 
221
 
 
222
  int getBaseIdx(double base);
 
223
 
 
224
  void addWord(TextWord *word);
 
225
 
 
226
private:
 
227
 
 
228
  int minBaseIdx;               // min baseline bucket index
 
229
  int maxBaseIdx;               // max baseline bucket index
 
230
  TextWord **pool;              // array of linked lists, one for each
 
231
                                //   baseline value (multiple of 4 pts)
 
232
  TextWord *cursor;             // pointer to last-accessed word
 
233
  int cursorBaseIdx;            // baseline bucket index of last-accessed word
 
234
 
 
235
  friend class TextBlock;
 
236
  friend class TextPage;
 
237
};
 
238
 
 
239
struct TextFlowData;
 
240
 
 
241
//------------------------------------------------------------------------
 
242
// TextLine
 
243
//------------------------------------------------------------------------
 
244
 
 
245
class TextLine {
 
246
public:
 
247
 
 
248
  TextLine(TextBlock *blkA, int rotA, double baseA);
 
249
  ~TextLine();
 
250
 
 
251
  void addWord(TextWord *word);
 
252
 
 
253
  // Return the distance along the primary axis between <this> and
 
254
  // <line>.
 
255
  double primaryDelta(TextLine *line);
 
256
 
 
257
  // Compares <this> to <line>, returning -1 (<), 0 (=), or +1 (>),
 
258
  // based on a primary-axis comparison, e.g., x ordering if rot=0.
 
259
  int primaryCmp(TextLine *line);
 
260
 
 
261
  // Compares <this> to <line>, returning -1 (<), 0 (=), or +1 (>),
 
262
  // based on a secondary-axis comparison of the baselines, e.g., y
 
263
  // ordering if rot=0.
 
264
  int secondaryCmp(TextLine *line);
 
265
 
 
266
  int cmpYX(TextLine *line);
 
267
 
 
268
  static int cmpXY(const void *p1, const void *p2);
 
269
 
 
270
  void coalesce(UnicodeMap *uMap);
 
271
 
 
272
  void visitSelection(TextSelectionVisitor *visitor,
 
273
                      PDFRectangle *selection,
 
274
                      SelectionStyle style);
 
275
 
 
276
  // Get the head of the linked list of TextWords.
 
277
  TextWord *getWords() { return words; }
 
278
 
 
279
  // Get the next TextLine on the linked list.
 
280
  TextLine *getNext() { return next; }
 
281
 
 
282
  // Returns true if the last char of the line is a hyphen.
 
283
  GBool isHyphenated() { return hyphenated; }
 
284
 
 
285
private:
 
286
 
 
287
  TextBlock *blk;               // parent block
 
288
  int rot;                      // text rotation
 
289
  double xMin, xMax;            // bounding box x coordinates
 
290
  double yMin, yMax;            // bounding box y coordinates
 
291
  double base;                  // baseline x or y coordinate
 
292
  TextWord *words;              // words in this line
 
293
  TextWord *lastWord;           // last word in this line
 
294
  Unicode *text;                // Unicode text of the line, including
 
295
                                //   spaces between words
 
296
  double *edge;                 // "near" edge x or y coord of each char
 
297
                                //   (plus one extra entry for the last char)
 
298
  int *col;                     // starting column number of each Unicode char
 
299
  int len;                      // number of Unicode chars
 
300
  int convertedLen;             // total number of converted characters
 
301
  GBool hyphenated;             // set if last char is a hyphen
 
302
  TextLine *next;               // next line in block
 
303
  Unicode *normalized;          // normalized form of Unicode text
 
304
  int normalized_len;           // number of normalized Unicode chars
 
305
  int *normalized_idx;          // indices of normalized chars into Unicode text
 
306
 
 
307
  friend class TextLineFrag;
 
308
  friend class TextBlock;
 
309
  friend class TextFlow;
 
310
  friend class TextWordList;
 
311
  friend class TextPage;
 
312
 
 
313
  friend class TextSelectionPainter;
 
314
  friend class TextSelectionSizer;
 
315
  friend class TextSelectionDumper;
 
316
};
 
317
 
 
318
//------------------------------------------------------------------------
 
319
// TextBlock
 
320
//------------------------------------------------------------------------
 
321
 
 
322
class TextBlock {
 
323
public:
 
324
 
 
325
  TextBlock(TextPage *pageA, int rotA);
 
326
  ~TextBlock();
 
327
 
 
328
  void addWord(TextWord *word);
 
329
 
 
330
  void coalesce(UnicodeMap *uMap);
 
331
 
 
332
  // Update this block's priMin and priMax values, looking at <blk>.
 
333
  void updatePriMinMax(TextBlock *blk);
 
334
 
 
335
  static int cmpXYPrimaryRot(const void *p1, const void *p2);
 
336
 
 
337
  static int cmpYXPrimaryRot(const void *p1, const void *p2);
 
338
 
 
339
  int primaryCmp(TextBlock *blk);
 
340
 
 
341
  double secondaryDelta(TextBlock *blk);
 
342
 
 
343
  // Returns true if <this> is below <blk>, relative to the page's
 
344
  // primary rotation.
 
345
  GBool isBelow(TextBlock *blk);
 
346
 
 
347
  void visitSelection(TextSelectionVisitor *visitor,
 
348
                      PDFRectangle *selection,
 
349
                      SelectionStyle style);
 
350
 
 
351
  // Get the head of the linked list of TextLines.
 
352
  TextLine *getLines() { return lines; }
 
353
 
 
354
  // Get the next TextBlock on the linked list.
 
355
  TextBlock *getNext() { return next; }
 
356
 
 
357
  void getBBox(double *xMinA, double *yMinA, double *xMaxA, double *yMaxA)
 
358
    { *xMinA = xMin; *yMinA = yMin; *xMaxA = xMax; *yMaxA = yMax; }
 
359
 
 
360
  int getLineCount() { return nLines; }
 
361
 
 
362
private:
 
363
 
 
364
  TextPage *page;               // the parent page
 
365
  int rot;                      // text rotation
 
366
  double xMin, xMax;            // bounding box x coordinates
 
367
  double yMin, yMax;            // bounding box y coordinates
 
368
  double priMin, priMax;        // whitespace bounding box along primary axis
 
369
 
 
370
  TextPool *pool;               // pool of words (used only until lines
 
371
                                //   are built)
 
372
  TextLine *lines;              // linked list of lines
 
373
  TextLine *curLine;            // most recently added line
 
374
  int nLines;                   // number of lines
 
375
  int charCount;                // number of characters in the block
 
376
  int col;                      // starting column
 
377
  int nColumns;                 // number of columns in the block
 
378
 
 
379
  TextBlock *next;
 
380
  TextBlock *stackNext;
 
381
 
 
382
  friend class TextLine;
 
383
  friend class TextLineFrag;
 
384
  friend class TextFlow;
 
385
  friend class TextWordList;
 
386
  friend class TextPage;
 
387
  friend class TextSelectionPainter;
 
388
};
 
389
 
 
390
//------------------------------------------------------------------------
 
391
// TextFlow
 
392
//------------------------------------------------------------------------
 
393
 
 
394
class TextFlow {
 
395
public:
 
396
 
 
397
  TextFlow(TextPage *pageA, TextBlock *blk);
 
398
  ~TextFlow();
 
399
 
 
400
  // Add a block to the end of this flow.
 
401
  void addBlock(TextBlock *blk);
 
402
 
 
403
  // Returns true if <blk> fits below <prevBlk> in the flow, i.e., (1)
 
404
  // it uses a font no larger than the last block added to the flow,
 
405
  // and (2) it fits within the flow's [priMin, priMax] along the
 
406
  // primary axis.
 
407
  GBool blockFits(TextBlock *blk, TextBlock *prevBlk);
 
408
 
 
409
  // Get the head of the linked list of TextBlocks.
 
410
  TextBlock *getBlocks() { return blocks; }
 
411
 
 
412
  // Get the next TextFlow on the linked list.
 
413
  TextFlow *getNext() { return next; }
 
414
 
 
415
private:
 
416
 
 
417
  TextPage *page;               // the parent page
 
418
  double xMin, xMax;            // bounding box x coordinates
 
419
  double yMin, yMax;            // bounding box y coordinates
 
420
  double priMin, priMax;        // whitespace bounding box along primary axis
 
421
  TextBlock *blocks;            // blocks in flow
 
422
  TextBlock *lastBlk;           // last block in this flow
 
423
  TextFlow *next;
 
424
 
 
425
  friend class TextWordList;
 
426
  friend class TextPage;
 
427
};
 
428
 
 
429
#if TEXTOUT_WORD_LIST
 
430
 
 
431
//------------------------------------------------------------------------
 
432
// TextWordList
 
433
//------------------------------------------------------------------------
 
434
 
 
435
class TextWordList {
 
436
public:
 
437
 
 
438
  // Build a flat word list, in content stream order (if
 
439
  // text->rawOrder is true), physical layout order (if <physLayout>
 
440
  // is true and text->rawOrder is false), or reading order (if both
 
441
  // flags are false).
 
442
  TextWordList(TextPage *text, GBool physLayout);
 
443
 
 
444
  ~TextWordList();
 
445
 
 
446
  // Return the number of words on the list.
 
447
  int getLength();
 
448
 
 
449
  // Return the <idx>th word from the list.
 
450
  TextWord *get(int idx);
 
451
 
 
452
private:
 
453
 
 
454
  GooList *words;                       // [TextWord]
 
455
};
 
456
 
 
457
#endif // TEXTOUT_WORD_LIST
 
458
 
 
459
//------------------------------------------------------------------------
 
460
// TextPage
 
461
//------------------------------------------------------------------------
 
462
 
 
463
class TextPage {
 
464
public:
 
465
 
 
466
  // Constructor.
 
467
  TextPage(GBool rawOrderA);
 
468
 
 
469
  void incRefCnt();
 
470
  void decRefCnt();
 
471
 
 
472
  // Start a new page.
 
473
  void startPage(GfxState *state);
 
474
 
 
475
  // End the current page.
 
476
  void endPage();
 
477
 
 
478
  // Update the current font.
 
479
  void updateFont(GfxState *state);
 
480
 
 
481
  // Begin a new word.
 
482
  void beginWord(GfxState *state, double x0, double y0);
 
483
 
 
484
  // Add a character to the current word.
 
485
  void addChar(GfxState *state, double x, double y,
 
486
               double dx, double dy,
 
487
               CharCode c, int nBytes, Unicode *u, int uLen);
 
488
 
 
489
  // End the current word, sorting it into the list of words.
 
490
  void endWord();
 
491
 
 
492
  // Add a word, sorting it into the list of words.
 
493
  void addWord(TextWord *word);
 
494
 
 
495
  // Add a (potential) underline.
 
496
  void addUnderline(double x0, double y0, double x1, double y1);
 
497
 
 
498
  // Add a hyperlink.
 
499
  void addLink(int xMin, int yMin, int xMax, int yMax, Link *link);
 
500
 
 
501
  // Coalesce strings that look like parts of the same line.
 
502
  void coalesce(GBool physLayout, GBool doHTML);
 
503
 
 
504
  // Find a string.  If <startAtTop> is true, starts looking at the
 
505
  // top of the page; else if <startAtLast> is true, starts looking
 
506
  // immediately after the last find result; else starts looking at
 
507
  // <xMin>,<yMin>.  If <stopAtBottom> is true, stops looking at the
 
508
  // bottom of the page; else if <stopAtLast> is true, stops looking
 
509
  // just before the last find result; else stops looking at
 
510
  // <xMax>,<yMax>.
 
511
  GBool findText(Unicode *s, int len,
 
512
                 GBool startAtTop, GBool stopAtBottom,
 
513
                 GBool startAtLast, GBool stopAtLast,
 
514
                 GBool caseSensitive, GBool backward,
 
515
                 double *xMin, double *yMin,
 
516
                 double *xMax, double *yMax);
 
517
 
 
518
  // Get the text which is inside the specified rectangle.
 
519
  GooString *getText(double xMin, double yMin,
 
520
                     double xMax, double yMax);
 
521
 
 
522
  void visitSelection(TextSelectionVisitor *visitor,
 
523
                      PDFRectangle *selection,
 
524
                      SelectionStyle style);
 
525
 
 
526
  void drawSelection(OutputDev *out,
 
527
                     double scale,
 
528
                     int rotation,
 
529
                     PDFRectangle *selection,
 
530
                     SelectionStyle style,
 
531
                     GfxColor *glyph_color, GfxColor *box_color);
 
532
 
 
533
  GooList *getSelectionRegion(PDFRectangle *selection,
 
534
                              SelectionStyle style,
 
535
                              double scale);
 
536
 
 
537
  GooString *getSelectionText(PDFRectangle *selection,
 
538
                              SelectionStyle style);
 
539
 
 
540
  // Find a string by character position and length.  If found, sets
 
541
  // the text bounding rectangle and returns true; otherwise returns
 
542
  // false.
 
543
  GBool findCharRange(int pos, int length,
 
544
                      double *xMin, double *yMin,
 
545
                      double *xMax, double *yMax);
 
546
 
 
547
  // Dump contents of page to a file.
 
548
  void dump(void *outputStream, TextOutputFunc outputFunc,
 
549
            GBool physLayout);
 
550
 
 
551
  // Get the head of the linked list of TextFlows.
 
552
  TextFlow *getFlows() { return flows; }
 
553
 
 
554
#if TEXTOUT_WORD_LIST
 
555
  // Build a flat word list, in content stream order (if
 
556
  // this->rawOrder is true), physical layout order (if <physLayout>
 
557
  // is true and this->rawOrder is false), or reading order (if both
 
558
  // flags are false).
 
559
  TextWordList *makeWordList(GBool physLayout);
 
560
#endif
 
561
 
 
562
private:
 
563
  
 
564
  // Destructor.
 
565
  ~TextPage();
 
566
  
 
567
  void clear();
 
568
  void assignColumns(TextLineFrag *frags, int nFrags, int rot);
 
569
  int dumpFragment(Unicode *text, int len, UnicodeMap *uMap, GooString *s);
 
570
 
 
571
  GBool rawOrder;               // keep text in content stream order
 
572
 
 
573
  double pageWidth, pageHeight; // width and height of current page
 
574
  TextWord *curWord;            // currently active string
 
575
  int charPos;                  // next character position (within content
 
576
                                //   stream)
 
577
  TextFontInfo *curFont;        // current font
 
578
  double curFontSize;           // current font size
 
579
  int nest;                     // current nesting level (for Type 3 fonts)
 
580
  int nTinyChars;               // number of "tiny" chars seen so far
 
581
  GBool lastCharOverlap;        // set if the last added char overlapped the
 
582
                                //   previous char
 
583
 
 
584
  TextPool *pools[4];           // a "pool" of TextWords for each rotation
 
585
  TextFlow *flows;              // linked list of flows
 
586
  TextBlock **blocks;           // array of blocks, in yx order
 
587
  int nBlocks;                  // number of blocks
 
588
  int primaryRot;               // primary rotation
 
589
  GBool primaryLR;              // primary direction (true means L-to-R,
 
590
                                //   false means R-to-L)
 
591
  TextWord *rawWords;           // list of words, in raw order (only if
 
592
                                //   rawOrder is set)
 
593
  TextWord *rawLastWord;        // last word on rawWords list
 
594
 
 
595
  GooList *fonts;                       // all font info objects used on this
 
596
                                //   page [TextFontInfo]
 
597
 
 
598
  double lastFindXMin,          // coordinates of the last "find" result
 
599
         lastFindYMin;
 
600
  GBool haveLastFind;
 
601
 
 
602
  GooList *underlines;          // [TextUnderline]
 
603
  GooList *links;               // [TextLink]
 
604
 
 
605
  int refCnt;
 
606
 
 
607
  friend class TextLine;
 
608
  friend class TextLineFrag;
 
609
  friend class TextBlock;
 
610
  friend class TextFlow;
 
611
  friend class TextWordList;
 
612
  friend class TextSelectionPainter;
 
613
  friend class TextSelectionDumper;
 
614
};
 
615
 
 
616
//------------------------------------------------------------------------
 
617
// ActualText
 
618
//------------------------------------------------------------------------
 
619
 
 
620
class ActualText {
 
621
public:
 
622
  // Create an ActualText
 
623
  ActualText(TextPage *out);
 
624
  ~ActualText();
 
625
 
 
626
  void addChar(GfxState *state, double x, double y,
 
627
               double dx, double dy,
 
628
               CharCode c, int nBytes, Unicode *u, int uLen);
 
629
  void beginMC(Dict *properties);
 
630
  void endMC(GfxState *state);
 
631
 
 
632
private:
 
633
  TextPage *text;
 
634
  int actualTextBMCLevel;       // > 0 when inside ActualText span. Incremented
 
635
                                // for each nested BMC inside the span.
 
636
  GooString *actualText;        // replacement text for the span
 
637
  GBool newActualTextSpan;      // true at start of span. used to init the extent
 
638
  double actualText_x, actualText_y; // extent of the text inside the span
 
639
  double actualText_dx, actualText_dy;
 
640
};
 
641
  
 
642
 
 
643
//------------------------------------------------------------------------
 
644
// TextOutputDev
 
645
//------------------------------------------------------------------------
 
646
 
 
647
class TextOutputDev: public OutputDev {
 
648
public:
 
649
 
 
650
  // Open a text output file.  If <fileName> is NULL, no file is
 
651
  // written (this is useful, e.g., for searching text).  If
 
652
  // <physLayoutA> is true, the original physical layout of the text
 
653
  // is maintained.  If <rawOrder> is true, the text is kept in
 
654
  // content stream order.
 
655
  TextOutputDev(char *fileName, GBool physLayoutA,
 
656
                GBool rawOrderA, GBool append);
 
657
 
 
658
  // Create a TextOutputDev which will write to a generic stream.  If
 
659
  // <physLayoutA> is true, the original physical layout of the text
 
660
  // is maintained.  If <rawOrder> is true, the text is kept in
 
661
  // content stream order.
 
662
  TextOutputDev(TextOutputFunc func, void *stream,
 
663
                GBool physLayoutA, GBool rawOrderA);
 
664
 
 
665
  // Destructor.
 
666
  virtual ~TextOutputDev();
 
667
 
 
668
  // Check if file was successfully created.
 
669
  virtual GBool isOk() { return ok; }
 
670
 
 
671
  //---- get info about output device
 
672
 
 
673
  // Does this device use upside-down coordinates?
 
674
  // (Upside-down means (0,0) is the top left corner of the page.)
 
675
  virtual GBool upsideDown() { return gTrue; }
 
676
 
 
677
  // Does this device use drawChar() or drawString()?
 
678
  virtual GBool useDrawChar() { return gTrue; }
 
679
 
 
680
  // Does this device use beginType3Char/endType3Char?  Otherwise,
 
681
  // text in Type 3 fonts will be drawn with drawChar/drawString.
 
682
  virtual GBool interpretType3Chars() { return gFalse; }
 
683
 
 
684
  // Does this device need non-text content?
 
685
  virtual GBool needNonText() { return gFalse; }
 
686
 
 
687
  //----- initialization and control
 
688
 
 
689
  // Start a page.
 
690
  virtual void startPage(int pageNum, GfxState *state);
 
691
 
 
692
  // End a page.
 
693
  virtual void endPage();
 
694
 
 
695
  //----- update text state
 
696
  virtual void updateFont(GfxState *state);
 
697
 
 
698
  //----- text drawing
 
699
  virtual void beginString(GfxState *state, GooString *s);
 
700
  virtual void endString(GfxState *state);
 
701
  virtual void drawChar(GfxState *state, double x, double y,
 
702
                        double dx, double dy,
 
703
                        double originX, double originY,
 
704
                        CharCode c, int nBytes, Unicode *u, int uLen);
 
705
 
 
706
  //----- grouping operators
 
707
  virtual void beginMarkedContent(char *name, Dict *properties);
 
708
  virtual void endMarkedContent(GfxState *state);
 
709
 
 
710
  //----- path painting
 
711
  virtual void stroke(GfxState *state);
 
712
  virtual void fill(GfxState *state);
 
713
  virtual void eoFill(GfxState *state);
 
714
 
 
715
  //----- link borders
 
716
  virtual void processLink(Link *link, Catalog *catalog);
 
717
 
 
718
  //----- special access
 
719
 
 
720
  // Find a string.  If <startAtTop> is true, starts looking at the
 
721
  // top of the page; else if <startAtLast> is true, starts looking
 
722
  // immediately after the last find result; else starts looking at
 
723
  // <xMin>,<yMin>.  If <stopAtBottom> is true, stops looking at the
 
724
  // bottom of the page; else if <stopAtLast> is true, stops looking
 
725
  // just before the last find result; else stops looking at
 
726
  // <xMax>,<yMax>.
 
727
  GBool findText(Unicode *s, int len,
 
728
                 GBool startAtTop, GBool stopAtBottom,
 
729
                 GBool startAtLast, GBool stopAtLast,
 
730
                 GBool caseSensitive, GBool backward,
 
731
                 double *xMin, double *yMin,
 
732
                 double *xMax, double *yMax);
 
733
 
 
734
  // Get the text which is inside the specified rectangle.
 
735
  GooString *getText(double xMin, double yMin,
 
736
                   double xMax, double yMax);
 
737
 
 
738
  // Find a string by character position and length.  If found, sets
 
739
  // the text bounding rectangle and returns true; otherwise returns
 
740
  // false.
 
741
  GBool findCharRange(int pos, int length,
 
742
                      double *xMin, double *yMin,
 
743
                      double *xMax, double *yMax);
 
744
 
 
745
  void drawSelection(OutputDev *out, double scale, int rotation,
 
746
                     PDFRectangle *selection,
 
747
                     SelectionStyle style,
 
748
                     GfxColor *glyph_color, GfxColor *box_color);
 
749
 
 
750
  GooList *getSelectionRegion(PDFRectangle *selection,
 
751
                              SelectionStyle style,
 
752
                              double scale);
 
753
 
 
754
  GooString *getSelectionText(PDFRectangle *selection,
 
755
                              SelectionStyle style);
 
756
 
 
757
#if TEXTOUT_WORD_LIST
 
758
  // Build a flat word list, in content stream order (if
 
759
  // this->rawOrder is true), physical layout order (if
 
760
  // this->physLayout is true and this->rawOrder is false), or reading
 
761
  // order (if both flags are false).
 
762
  TextWordList *makeWordList();
 
763
#endif
 
764
 
 
765
  // Returns the TextPage object for the last rasterized page,
 
766
  // transferring ownership to the caller.
 
767
  TextPage *takeText();
 
768
 
 
769
  // Turn extra processing for HTML conversion on or off.
 
770
  void enableHTMLExtras(GBool doHTMLA) { doHTML = doHTMLA; }
 
771
 
 
772
private:
 
773
 
 
774
  TextOutputFunc outputFunc;    // output function
 
775
  void *outputStream;           // output stream
 
776
  GBool needClose;              // need to close the output file?
 
777
                                //   (only if outputStream is a FILE*)
 
778
  TextPage *text;               // text for the current page
 
779
  GBool physLayout;             // maintain original physical layout when
 
780
                                //   dumping text
 
781
  GBool rawOrder;               // keep text in content stream order
 
782
  GBool doHTML;                 // extra processing for HTML conversion
 
783
  GBool ok;                     // set up ok?
 
784
 
 
785
  ActualText *actualText;
 
786
};
 
787
 
 
788
#endif